大家好,关于CV高级技巧篇【6】——连通域与距离变换算法优化很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助!
声明:创作不易,未经授权不得复制转载statement:No reprinting without authorization
内容概述
1、连通域
• 实现图像的快速连通域算法,可以提取图像中的连通域,并以不同的颜色显示不同的连通域。
• 对于二值图像,删除较小的前景区域并仅保留最大的前景区域。
2、距离变换
• 了解OpenCV 的距离变换函数distanceTransform,使用适当的测试图像进行测试,并可视化距离场输出。
一、快速连通域算法的实现
首先,输入源图像仅扫描一次。如图所示的四域结构用于确定连通域。向量容器用于存储图像连通域的标签信息。对于二值图像,黑色是背景像素。 (0),白色为前景像素(255),前景像素被标记,背景被标记为-1。
扫描时采用一次扫描+合并等价类来实现,采用顺序扫描。从左到右,中间的像素有四种情况,处理如下:
image.png
具体相关代码如下:
//剩余行-1行
for (int i=1; i inputImage.rows; i++)
{
const uchar* lastrowData=inputImage.ptr(i-1);//上一行的行指针
const uchar* rowData=inputImage.ptr(i);//本行的行指针
if(行数据[0]==0)
labelImg.push_back(-1);
别的{
if (1==LastrowData[0])
labelImg.push_back(labelImg[(i-1)*cols]);
别的{
计数++;
labelImg.push_back(++labelNum);
}
}
for (int j=1; j 列; j++)
{
int a=labelImg[(i - 1)*cols + j];
int b=labelImg[i*cols + j - 1];
if (行数据[j]==0)
labelImg.push_back(-1);
别的{
if (0==rowData[j - 1] 0==lastrowData[j]) {
计数++;
labelImg.push_back(++labelNum);
}
否则if (1==rowData[j - 1] 0==lastrowData[j])
labelImg.push_back(b);
否则if (0==rowData[j - 1] 1==lastrowData[j])
labelImg.push_back(a);
别的{
如果(a!=b){
for (size_t k=0; k labelImg.size(); k++)
{
if (labelImg[k]==b)
labelImg[k]=a;
}
labelImg.push_back(a);
数数- ;
}
别的{
labelImg.push_back(a);
}
}
}
}
对于得到的标签向量,连通域将被标记为相同的数字,并且向量的大小将等于图像的像素值。提取后,大于0标记的像素被分配为红色,如图所示:
image.png
二、对不同的连通于进行着色
首先创建一个三通道的目标显示图像,然后根据标签值分配不同的颜色,如下图:
void bepaint(const Mat simg,Mat dimg, 矢量labelImg) {
int rows=simg.rows;
int cols=simg.cols;
释放();
dimg.create(行、列、CV_8UC3);
暗淡=标量:all(0);
for (int i=0; i 行; i++) {
for (int j=0; j 列; j++) {
int x=labelImg[i*cols + j];
如果(x==-1){
dimg.at(i, j)[0]=255;
dimg.at(i, j)[1]=255;
dimg.at(i, j)[2]=255;
}
别的{
dimg.at(i, j)[0]=(x*x*x*x) % 255;
dimg.at(i, j)[1]=(x*x*x) % 255;
dimg.at(i, j)[2]=(x*x) % 255;
}
}
}
}效果如下:image.pngimage.png
三、删除较小的前景区域,保留最大连通域
对于一次扫描后可以获得的标签数量(连通域数量),可以动态创建一个标签结构数组,遍历每个连通域的像素数量。统计,最终得到最大的连通域,显示如下:
image.png
四、距离变换函数
功能:用于计算原图像中距离变换后的图像;
void distanceTransform( InputArray src, OutputArray dst, OutputArray labels, int distanceType, int maskSize, int labelType=DIST_LABEL_CCOMP );
功能说明:
它用于计算图像中每个非零像素与其最近的零像素之间的距离。输出是保存每个非零点与最近的零点之间的距离信息;图像上的点越亮,离零点越远。
参数:src 是单通道8位二值图像(只有0或1)
dst表示距离计算的输出图像,可以制作单通道32bit浮点数据
distanceType表示选择距离的类型,可以设置为CV_DIST_L1、CV_DIST_L2、CV_DIST_C等,如下:
DIST_L1=1, //!距离=|x1-x2| + |y1-y2|
DIST_L2=2, //!简单欧氏距离
DIST_C=3, //!距离=max(|x1-x2|,|y1-y2|)
DIST_L12=4, //! L1-L2 公制: 距离=2(sqrt(1+x*x/2) - 1))
DIST_FAIR=5, //!距离=c^2(|x|/c-log(1+|x|/c)),c=1.3998
DIST_WELSCH=6, //!距离=c2/2(1-exp(-(x/c)2)), c=2.9846
DIST_HUBER=7 //!距离=|x|
maskSize表示距离变换掩码模板,可以设置为3、5或CV_DIST_MASK_PRECISE。在CV_DIST_L1 或CV_DIST_C 的情况下,参数值被迫设置为3,因为33 掩模给出与55 掩模相同的结果。甚至更快。
labels 表示可选的输出二维数组;
labelType表示输出二维数组的类型;
首先使用高斯滤波和阈值函数对原始图像进行优化和阈值(二值化)得到输入图像,然后调用distanceTransform函数得到距离场图像,显示如下:
关于CV高级技巧篇【6】——连通域与距离变换算法优化的内容到此结束,希望对大家有所帮助。
【CV高级技巧篇【6】——连通域与距离变换算法优化】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
终于可以学习更高级的CV操作了!
有16位网友表示赞同!
我一直对连通域运算感兴趣,这篇文章能给我带来很多启发吗?
有9位网友表示赞同!
距离变换,听起来好厉害的样子啊,以后做图像分析的时候能派上用场吗?
有11位网友表示赞同!
感觉这个标题很有技术含量,期待看一看具体的内容!
有13位网友表示赞同!
我平时在处理一些图像数据,好像可以利用连通域和距离变换来提高效率吧。
有17位网友表示赞同!
对CV编程不太懂,但希望能从这篇文章中学到一些基础知识!
有7位网友表示赞同!
感觉学习这些进阶操作需要有些数学基础吗?
有14位网友表示赞同!
有没有什么简单易懂的示例代码可以跟着学习呢?
有20位网友表示赞同!
这篇文章会介绍几种不同的算法实现方法吗?
有11位网友表示赞同!
希望文章能够详细解释连通域和距离变换的概念和应用场景。
有12位网友表示赞同!
我平时对图像分割很有兴趣,这些操作可能能帮助我更好地理解吧!
有10位网友表示赞同!
感觉学完这篇文章,我可以更深入地进行图像分析了!
有10位网友表示赞同!
这个主题听起来真的很酷啊,我要看看它到底是怎么运作的!
有9位网友表示赞同!
我一直想学习CV高级知识,这篇文章看来是个不错的选择!
有9位网友表示赞同!
期待看到一些实际应用案例,让我更好地理解这些操作的价值!
有6位网友表示赞同!
希望文章能够提供一些代码实现和调试技巧,方便我上手练习。
有11位网友表示赞同!
我很想学习如何用这些技术来处理我的项目数据!
有8位网友表示赞同!
这篇文章能帮助我解决图像处理中遇到的的一些难题吧?
有20位网友表示赞同!
学习新的知识总让人兴奋,希望这篇文章能够给我带来启发!
有15位网友表示赞同!