【数字图像处理】求包含白色点得最小凸多边形
来源:互联网 发布:青岛学淘宝学校 编辑:程序博客网 时间:2024/04/30 05:47
题目:一幅图像,背景为黑色,其中包含一些白色孤点,求包含白色点的最小的凸多边形。
比如图像:
思路:首先找到最下方的白色点。然后遍历每个白色点,求出当前点V1与每个白色点连成的方向向量。找出与单位向量向量(0,1)(当前向量)内积最小的那个方向向量。组成那个向量的白点即和V1相邻的下一个点V2。接着,更新当前向量为V1和V2连成的单位向量。再遍历每个白点,求出当前点V2和每个白色点连成的方向向量。找出与当前向量内积最小的那个单位向量。组成那个向量的白点即和V2相邻的下一个点V3。接着找出和V3相邻的下一个点。直到下一个点变为V1.即所有的边缘点都已找到。
参考代码:
%寻找包围白色点的最小的凸多边形%生成一幅包含多个白色像素点的图片height = 256;%图像高度width = 256;%图像宽度I = zeros(height,width);%在图像中生成N个白色点I(10,20) = 255;I(30,50) = 255;I(150,90) = 255;I(240,100) = 255;I(45,220) = 255;I(90,90) = 255;I(230,10) = 255;I(220,240) = 255;% I = imread('pp.jpg');figure,imshow(I)% [height,width] = size(I);%寻找最下方的白色点%注意此处跳出二重循环!!!for i = height:-1:1 flag = 0;%标记是是否找到 for j = width:-1:1 if i >= 1 && j >= 1 && I(i,j) == 255 lowest_i = i; lowest_j = j;%记录最下方的点得坐标 flag = 1;%已找到 break; end end if flag == 1%已找到,跳出循环 break; endendMAXNUM = 9999999;count = 0;%记录图像中白色点的数目loca = zeros(MAXNUM,2);%记录各白色点的坐标for i = 1:height for j = 1:width if I(i,j) == 255 count = count + 1;%白色点数目增加一 loca(count,1) = i; loca(count,2) = j; end endend%按序寻找位于凸多边形上的白色点NumVetex = 0;%记录边缘点的个数LocVetex = zeros(count,2);%按序记录各边缘点的坐标%加入最下方的点NumVetex = NumVetex + 1;LocVetex(NumVetex,1) = lowest_i;LocVetex(NumVetex,2) = lowest_j;current_i = lowest_i;%当前点得坐标current_j = lowest_j;next_i = -1;%与当前点相邻的下一个位于凸多边形上面的白色点的坐标next_j = -1;while next_i ~= lowest_i && next_j ~= lowest_j%终止条件:回到最下方的点 if current_i == lowest_i && current_j == lowest_j%第一个点 current_prod_i = 0;%当前单位向量 current_prod_j = 1; end MaxProd = -999999;%最大内积 %寻找下一个点:内积最大 for i = 1:count if current_i ~= loca(i,1) && current_j ~= loca(i,2)%跳过当前点 %求其他点和当前点组成的向量 prod_x = loca(i,1) - current_i; prod_y = loca(i,2) - current_j; %单位化 prod_length = sqrt(prod_x * prod_x + prod_y * prod_y); prod_x = prod_x / prod_length; prod_y = prod_y / prod_length; TempProd = prod_x * current_prod_i + prod_y * current_prod_j; if MaxProd < TempProd%找到更大的内积 MaxProd = TempProd; next_i = loca(i,1);%记录内积更大的点,即下一个边缘点 next_j = loca(i,2); end end end %把下一个点加入边缘点坐标数组 NumVetex = NumVetex + 1; LocVetex(NumVetex,1) = next_i; LocVetex(NumVetex,2) = next_j; %修改变量 %当前单位向量变化 prod_length = sqrt((next_i - current_i) * (next_i - current_i) + (next_j - current_j) * (next_j - current_j)); current_prod_i = (next_i - current_i) / prod_length; current_prod_j = (next_j - current_j) / prod_length; %当前点后移 current_i = next_i; current_j = next_j;end%绘制多边形的边for i = 2:NumVetex grad = (LocVetex(i,2) - LocVetex(i - 1,2)) / (LocVetex(i,1) - LocVetex(i - 1,1));%直线斜率 if LocVetex(i - 1,1) < LocVetex(i,1) for index_i = LocVetex(i - 1,1):LocVetex(i,1) index_j = LocVetex(i - 1,2) + grad * (index_i - LocVetex(i - 1,1)); index_j = uint8(index_j); I(index_i,index_j) = 255; end else for index_i = LocVetex(i - 1,1):-1:LocVetex(i,1) index_j = LocVetex(i - 1,2) + grad * (index_i - LocVetex(i - 1,1)); index_j = uint8(index_j); I(index_i,index_j) = 255; end endendfigure,imshow(I)
运行结果:
- 【数字图像处理】求包含白色点得最小凸多边形
- MATLAB 中求解包含所有数据点的最小凸多边形
- 求包含点集的最小正方形个数。
- (hdu step 7.1.7)Wall(求凸包的周长——求将所有点围起来的最小凸多边形的周长)
- 求高手解答,数字图像处理!!!!
- 数字图像处理之点运算
- 暴力求包含n个点的圆的最小半径
- 数字图像处理:第四章 点运算
- 数字图像处理不得不知的点(1)
- 数字图像处理不得不知的点(2)
- 数字图像处理不得不知的点(3)
- 凸多边形间最小距离
- 求凸多边形距离
- 求包含字符集的最小子串
- poj 3608 Bridge Across Islands, 旋转卡壳求凸多边形间最小距离
- 数字图像和数字图像处理
- 凸多边形最小面积外接矩形
- 凸多边形最小周长外接矩形
- 各种计算机语言的经典书籍 (******)
- zoj 1891
- POJ-2236 wireless network 并查集
- 不良代码展示-两个数组找不同
- 10.4 多边形面积
- 【数字图像处理】求包含白色点得最小凸多边形
- Penalty Records - GROUP BY; HAVING; UNION;
- Eclipse下C/C++环境搭建
- 编程之美-- 烙饼排序问题
- 滤了asa,cer,cdx,php,aspx等脚本类型的上传情况下添加一个ashx的上传类型
- ssh2之java.lang.reflect.InvocationTargetException
- TestCase的约定
- 一个简单的(也可以说是不完全的)IMAP类和应用。(一)
- 一个简单的(也可以说是不完全的)IMAP类和应用。(二)