contor expansion

本文详细介绍了康托展开及其逆过程的概念与应用。通过数学公式和实例解析了如何将排列映射为数值及如何从数值反推排列的方法。提供了具体的代码实现帮助读者理解。

康托展开

公式:X=a[n](n-1)!+a[n-1](n-2)!+…+a[i]*(i-1)!+…+a[1]*0!
其中a[i]为当前未出现的元素中是排在第几个(从0开始)。
用于将一组排列映射为一个值。
例如一个字符串 s=”dbac”。
a[4]=3.d>b,d>a,d>c. 从0开始它排第三。
同理 a[3]=1,a[2]=0,a[1]=0。
X(s)=3*3!+1*2!+0*1!+0*0!=20.
代码如下:

int jc[12] = { 1,1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800 } ;
int KT(int n,char s[])
{
    int i,j,t,sum;
    sum=0;
    for(i=0; i<n; i++)
    {
        t=0;
        for(j=i+1; j<n; j++)
        {
            if(s[j]<s[i])
            {
                t++;
            }
        }
        sum+=t*jc[n-i-1];
    }
    return sum+1;//加1主要是为了让第一个排列从1开始而不是0
}

逆康托展开

已知一组序列,我们能否把这段序列的所有排列中第k小的序列求出来呢?
其实关键是求上述的a[n]。
如上述的s=”dbac”
转载

int jc[12] = { 1,1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800 } ;
int vis[12] ;
int main()
{
    int n=4,k=3;///第三小的排列
    char s[]="abcd";
    ///逆康托展开
    k--;///第1小 X(s)=0
    memset(vis,0,sizeof vis);
    int o=0,j;
    for(int i=n-1; i>=0; i--)
    {
        int t;
        t=k/jc[i];
        k%=jc[i];
        for(j=1; j<=n; j++)
        {
            if(!vis[j])
            {
                if(t==0) break;
                t--;
            }
        }
        vis[j]=1;
        printf("%c",j+'a'-1);
    }
    printf("\n");
    return 0 ;
}
import cv2 import numpy as np import os def process_image(image_path, output_folder, min_side_threshold, expansion): """ 在指定图像的ROI区域内检测红色、绿色、蓝色及白色区域,并返回每个符合条件的大区域的外接矩形角点坐标。 参数: image_path (str): 图像文件路径。 output_folder (str): 输出文件夹路径,用于保存处理后的图像。 min_side_threshold (int): 最小边长阈值,用于过滤太小的检测区域,默认150像素。 expansion (int): 外接矩形扩展像素数,避免裁剪边界,默认4。 返回: list: 每个符合条件的大区域的外接矩形角点坐标列表,格式为 [(x1, y1, x2, y2)]。 """ #1. 读取图片 image = cv2.imread(image_path) if image is None: print("图像加载失败,请检查路径") exit() #2. 选择ROI区域 roi = cv2.selectROI("Select ROI", image, showCrosshair=True, fromCenter=False) cv2.destroyWindow("Select ROI") (x, y, w, h) = roi if w == 0 or h == 0: imCrop = image else: imCrop = image[y:y+h, x:x+w] #3. 转换为 HSV 颜色空间 hsv = cv2.cvtColor(imCrop, cv2.COLOR_BGR2HSV) #白色部分内容转换为灰度图 gray = cv2.cvtColor(imCrop, cv2.COLOR_BGR2GRAY) ########################检测彩色区域############# # 检测红色 # 红色在 HSV 中有两个范围:低 H 和高 H(因为色环是环形) lower_red1 = np.array([0, 100, 100]) # 红色下界1 upper_red1 = np.array([10, 255, 255]) lower_red2 = np.array([170, 100, 100]) # 红色下界2 upper_red2 = np.array([180, 255, 255]) mask1 = cv2.inRange(hsv, lower_red1, upper_red1) mask2 = cv2.inRange(hsv, lower_red2, upper_red2) red_mask = cv2.bitwise_or(mask1, mask2) # 检测蓝色 lower_blue = np.array([100, 100, 100]) upper_blue = np.array([130, 255, 255]) blue_mask = cv2.inRange(hsv, lower_blue, upper_blue) # 检测绿色 lower_green = np.array([40, 100, 100]) upper_green = np.array([80, 255, 255]) green_mask = cv2.inRange(hsv, lower_green, upper_green) # 可视化各个颜色掩码 cv2.imshow("Red Mask", red_mask) cv2.imshow("Blue Mask", blue_mask) cv2.imshow("Green Mask", green_mask) #4. 合并所有颜色区域 color_mask = cv2.bitwise_or(cv2.bitwise_or(red_mask, blue_mask), green_mask) ##############检测白色区域########## # 白色:高亮度 + 低饱和度 lower_white = np.array([0, 0, 200]) # V > 200,接近白色 upper_white = np.array([180, 30, 255]) # S < 30,避免彩色干扰 mask_white = cv2.inRange(hsv, lower_white, upper_white) #结合灰度图增强白色检测效果 _, mask_white_gray = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY) mask_white = cv2.bitwise_or(mask_white, mask_white_gray) #5. 合并所有掩码(彩色 + 白色) combined_mask = cv2.bitwise_or(color_mask, mask_white) # 二值化处理 _, binary = cv2.threshold(combined_mask, 127, 255, cv2.THRESH_BINARY) # 固定阈值二值化 #6. 形态学操作,去除噪点,连接断裂区域 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5)) binary = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel) #7. 查找轮廓 contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if not contours: print("未检测到任何轮廓") else: # min_side_threshold = 150 # 8. 遍历每个轮廓,筛选有效区域 for i, contour in enumerate(contours): # 获取当前轮廓点 contour_points = contour.reshape(-1, 2) if len(contour_points) >= 3: # 计算最小外接矩形 rect = cv2.minAreaRect(contour_points) width, height = rect[1] # 获取宽高 # 跳过过小的矩形(任一方向边长不足阈值) if min(width, height) < min_side_threshold: continue # 外扩矩形,增加外扩量 # expansion = 4 # center, (w, h), angle = rect # rect_expanded = (center, (w + expansion, h + expansion), angle) rect_expanded = (rect[0], (rect[1][0] + expansion, rect[1][1] + expansion), rect[2]) #9. 获取矩形角点并排序 box = cv2.boxPoints(rect_expanded) box = np.int32(box) box = sorted(box, key=lambda x: (x[0], x[1])) box = np.array([box[0], box[2], box[3], box[1]]) # 左上开始顺时针 top_left = tuple(box[0]) #10. 绘制矩形和编号 color = (0, 255 - i*50, 100 + i*50) # 自动生成不同颜色 cv2.drawContours(imCrop, [box], 0, color, 2) cv2.putText(imCrop, str(i+1), top_left, cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) # # 将框的坐标转换回原图坐标系 box[:, 0] += roi[0] # x坐标加上ROI的x偏移 box[:, 1] += roi[1] # y坐标加上ROI的y偏移 # 输出坐标信息,先输出i最大的那个,也就是从右下角开始输出 print(f"\n区域 {i+1} 坐标:") print(f"Top-Left: {tuple(box[0])}, Top-Right: {tuple(box[1])}, Bottom-Right: {tuple(box[2])}, Bottom-Left: {tuple(box[3])}") #11. 保存结果 output_path = os.path.join(output_folder, f"processed_{os.path.basename(image_path)}") cv2.imwrite(output_path, image) print(f"处理结果已保存到: {output_path}") #12. 显示结果 cv2.imshow("Original Image", image) cv2.imshow("Combined Mask", combined_mask) cv2.imshow("Segmented Result", imCrop) cv2.waitKey(0) cv2.destroyAllWindows() # 主程序 if __name__ == "__main__": input_folder = '/home/incam/Desktop/mycode/template/CAD/22' output_folder = '/home/incam/Desktop/mycode/template/CAD/22/CAD11/' # 确保输出文件夹存在 os.makedirs(output_folder, exist_ok=True) # 处理文件夹中的所有图片 for filename in os.listdir(input_folder): if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp')): image_path = os.path.join(input_folder, filename) process_image(image_path, output_folder, min_side_threshold=150, expansion=4) 当前代码是对原始图片截取ROI进行处理,如果我想对原始图片进行所有的操作应该怎么该
10-11
import cv2 import numpy as np import os # from scipy.cluster.hierarchy import fcluster, linkage # from scipy.spatial.distance import pdist # image = cv2.imread('/home/incam/Desktop/mycode/template/CAD/orig_img/111.png') # cv2.imshow('Origin', image) # # 定义ROI的矩形框 #8 167 1907 968 # x, y, width, height = 206, 4, 1236, 951#8, 167, 1907, 968#22,232,1876,730# # #21,250,1882,671 #22 353 1881 509 #black2:22,232,1876,730 # roi = (x, y, width, height) # # 利用ROI截取区域 # cropped_image = image[roi[1]:roi[1]+roi[3], roi[0]:roi[0]+roi[2]] # cv2.imshow('Result - Me', cropped_image) img_path = '/home/incam/Desktop/mycode/template/CAD/cad/Snipaste_2025-09-09_16-38-23.png' # Read image img = cv2.imread(img_path) # 创建一个窗口 #cv2.namedWindow("image", flags= cv2.WINDOW_NORMAL | cv2.WINDOW_FREERATIO) #cv2.namedWindow("image_roi", flags= cv2.WINDOW_NORMAL | cv2.WINDOW_FREERATIO) cv2.imshow("image", img) # 是否显示网格 showCrosshair = False # 如果为Ture的话 , 则鼠标的起始位置就作为了roi的中心 # False: 从左上角到右下角选中区域 fromCenter = False # 选择 ROI(感兴趣的部分)图像 选择后按回车确认,按ESC取消 roi = cv2.selectROI("image", img, showCrosshair, fromCenter) (x, y, w, h) = roi # 截取的图像 imCrop = img[y : y+h, x:x+w] print(x,y,w,h) # 显示截取图像 cv2.imshow("image_roi", imCrop) # 1. 预处理:灰度化 + 高斯去模糊降噪 + 二值化 + 形态学闭操作 gray = cv2.cvtColor(imCrop, cv2.COLOR_BGR2GRAY) # gray = cv2.cvtColor(cropped_image, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray, (5, 5), 0) _, binary = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) ''' 原始二值图像中,某些本应属于同一逻辑区域的内容(如一个矩形主体 + 旁边的标注文字/引线)被 OpenCV 分割成了多个独立轮廓; # 方法1的第二步: 查找所有轮廓 contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 所以cv2.findContours 是通过找到多个小轮廓 → 每个轮廓都生成一个矩形 → 无法生成一个包含整体的大矩形; ''' # 形态学闭操作连接微小间隙(使用形态学操作才能分割出完整轮廓) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5)) binary = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel) #MORPH_CLOSE是先膨胀后腐蚀的操作,能够填充小的孔洞或缝隙,连接邻近的前景区域,平滑轮廓边界 # 2. 查找所有外部轮廓 contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if not contours: print("未检测到任何轮廓") else: #####根据边长筛选最小外接矩形框,设定最小边长阈值 min_side_threshold = 150 # 3. 处理每个轮廓 for i, contour in enumerate(contours): # 获取当前轮廓点 contour_points = contour.reshape(-1, 2) if len(contour_points) >= 3: # 计算最小外接矩形 rect = cv2.minAreaRect(contour_points) width, height = rect[1] # 获取宽高 # 跳过过小的矩形(任一方向边长不足阈值) if min(width, height) < min_side_threshold: continue # 外扩**个像素,确保外接矩形包含所有点 expansion = 2 rect = (rect[0], (rect[1][0] + expansion*2, rect[1][1] + expansion*2), rect[2]) # 获取矩形角点并排序 box = cv2.boxPoints(rect) box = np.int32(box) box = sorted(box, key=lambda x: (x[0], x[1])) box = np.array([box[0], box[2], box[3], box[1]]) # 左上开始顺时针 # # 绘制矩形和编号 # color = (0, 255 - i*50, 100 + i*50) # 自动生成不同颜色 # # cv2.drawContours(image, [box], 0, color, 2) # cv2.drawContours(imCrop, [box], 0, color, 2) cv2.drawContours(imCrop, [box], 0, (0, 255, 0), 2) # cv2.putText(image, str(i+1), tuple(box[0]), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0,0,255), 2) # # 将框的坐标转换回原图坐标系 box[:, 0] += roi[0] # x坐标加上ROI的x偏移 box[:, 1] += roi[1] # y坐标加上ROI的y偏移 # 输出坐标信息,先输出i最大的那个,也就是从右下角开始输出 # print(f"\n区域 {i+1} 坐标:") print(f"Top-Left: {tuple(box[0])}, Top-Right: {tuple(box[1])}, Bottom-Right: {tuple(box[2])}, Bottom-Left: {tuple(box[3])}") # 高斯双边滤波 ''' * 双边滤波参数: * 15--->计算半径,半径之内的都会被纳入计算,如果提供-1则根据sigma space参数进行计算 * 100--->sigma color 决定多少差值之内的像素会被计算 * 5----->sigma space 如果d的值大于0则申明无效,否则根据他来计算d的值 ''' # bilateralMat = cv2.bilateralFilter(image, 15, 50, 5) # cv2.imshow("bilateralMat", bilateralMat) # # 锐化操作 # kernel = np.array([[0, -1, 0], # [-1, 5, -1], # [0, -1, 0]], dtype=np.int32) # resultImage = cv2.filter2D(bilateralMat, -1, kernel) # # 显示结果 # cv2.imshow('Result - Merged Bounding Boxes', resultImage) # # cv2.imwrite('CAD/result_merged_boxes.jpg', image) # cv2.imwrite('CAD/result_merged_boxes.jpg', resultImage) # cv2.waitKey(0) # cv2.destroyAllWindows() # 4. 显示结果 cv2.imshow('Multi-Object Detection', img) # cv2.imwrite('multi_result.png', image) cv2.waitKey(0) cv2.destroyAllWindows() 这段代码检测土坯indows() 这段代码检测土坯ianBlur(gray, (5, 5), 0) _, binary = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) ''' 原始二值图像中,某些本应属于同一逻辑区域的内容(如一个矩形主体 + 旁边的标注文字/引线)被 OpenCV 分割成了多个独立轮廓; # 方法1的第二步: 查找所有轮廓 contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 所以cv2.findContours 是通过找到多个小轮廓 → 每个轮廓都生成一个矩形 → 无法生成一个包含整体的大矩形; ''' # 形态学闭操作连接微小间隙(使用形态学操作才能分割出完整轮廓) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5)) binary = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel) #MORPH_CLOSE是先膨胀后腐蚀的操作,能够填充小的孔洞或缝隙,连接邻近的前景区域,平滑轮廓边界 # 2. 查找所有外部轮廓 contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if not contours: print("未检测到任何轮廓") else: #####根据边长筛选最小外接矩形框,设定最小边长阈值 min_side_threshold = 150 # 3. 处理每个轮廓 for i, contour in enumerate(contours): # 获取当前轮廓点 contour_points = contour.reshape(-1, 2) if len(contour_points) >= 3: # 计算最小外接矩形 rect = cv2.minAreaRect(contour_points) width, height = rect[1] # 获取宽高 # 跳过过小的矩形(任一方向边长不足阈值) if min(width, height) < min_side_threshold: continue # 外扩**个像素,确保外接矩形包含所有点 expansion = 2 rect = (rect[0], (rect[1][0] + expansion*2, rect[1][1] + expansion*2), rect[2]) # 获取矩形角点并排序 box = cv2.boxPoints(rect) box = np.int32(box) box = sorted(box, key=lambda x: (x[0], x[1])) box = np.array([box[0], box[2], box[3], box[1]]) # 左上开始顺时针 # # 绘制矩形和编号 # color = (0, 255 - i*50, 100 + i*50) # 自动生成不同颜色 # # cv2.drawContours(image, [box], 0, color, 2) # cv2.drawContours(imCrop, [box], 0, color, 2) cv2.drawContours(imCrop, [box], 0, (0, 255, 0), 2) # cv2.putText(image, str(i+1), tuple(box[0]), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0,0,255), 2) # # 将框的坐标转换回原图坐标系 box[:, 0] += roi[0] # x坐标加上ROI的x偏移 box[:, 1] += roi[1] # y坐标加上ROI的y偏移 # 输出坐标信息,先输出i最大的那个,也就是从右下角开始输出 # print(f"\n区域 {i+1} 坐标:") print(f"Top-Left: {tuple(box[0])}, Top-Right: {tuple(box[1])}, Bottom-Right: {tuple(box[2])}, Bottom-Left: {tuple(box[3])}") # 高斯双边滤波 ''' * 双边滤波参数: * 15--->计算半径,半径之内的都会被纳入计算,如果提供-1则根据sigma space参数进行计算 * 100--->sigma color 决定多少差值之内的像素会被计算 * 5----->sigma space 如果d的值大于0则申明无效,否则根据他来计算d的值 ''' # bilateralMat = cv2.bilateralFilter(image, 15, 50, 5) # cv2.imshow("bilateralMat", bilateralMat) # # 锐化操作 # kernel = np.array([[0, -1, 0], # [-1, 5, -1], # [0, -1, 0]], dtype=np.int32) # resultImage = cv2.filter2D(bilateralMat, -1, kernel) # # 显示结果 # cv2.imshow('Result - Merged Bounding Boxes', resultImage) # # cv2.imwrite('CAD/result_merged_boxes.jpg', image) # cv2.imwrite('CAD/result_merged_boxes.jpg', resultImage) # cv2.waitKey(0) # cv2.destroyAllWindows() # 4. 显示结果 cv2.imshow('Multi-Object Detection', img) # cv2.imwrite('multi_result.png', image) cv2.waitKey(0) cv2.destroyAllWindows() 这段代码检测土坯indows() 这段代码检测图片绘制内容的最小外接矩形框,然而还是有些内容的矩形框巍峨ult.png', image) cv2.waitKey(0) cv2.destroyAllWindows() 这段代码检测图片绘制内容的最小外接矩形框,然而还是有些内容的矩形框无法识别出来,也就没办法绘制了,问题出在哪里?二值化结果不够好吗?还是什么?如果我加入一个边缘检测算子识别会好一点吗?
10-01
【无人机】基于改进粒子群算法的无人机路径规划研究[和遗传算法、粒子群算法进行比较](Matlab代码实现)内容概要:本文围绕基于改进粒子群算法的无人机路径规划展开研究,重点探讨了在复杂环境中利用改进粒子群算法(PSO)实现无人机三维路径规划的方法,并将其与遗传算法(GA)、标准粒子群算法等传统优化算法进行对比分析。研究内容涵盖路径规划的多目标优化、避障策略、航路点约束以及算法收敛性和寻优能力的评估,所有实验均通过Matlab代码实现,提供了完整的仿真验证流程。文章还提到了多种智能优化算法在无人机路径规划中的应用比较,突出了改进PSO在收敛速度和全局寻优方面的优势。; 适合人群:具备一定Matlab编程基础和优化算法知识的研究生、科研人员及从事无人机路径规划、智能优化算法研究的相关技术人员。; 使用场景及目标:①用于无人机在复杂地形或动态环境下的三维路径规划仿真研究;②比较不同智能优化算法(如PSO、GA、蚁群算法、RRT等)在路径规划中的性能差异;③为多目标优化问题提供算法选型和改进思路。; 阅读建议:建议读者结合文中提供的Matlab代码进行实践操作,重点关注算法的参数设置、适应度函数设计及路径约束处理方式,同时可参考文中提到的多种算法对比思路,拓展到其他智能优化算法的研究与改进中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值