当前位置:首页 » 操作系统 » 连通区域标记算法

连通区域标记算法

发布时间: 2022-06-17 17:01:31

1. 如何将几个连通区域分别用矩形框标注出来

图像处理里有一种叫做Labeling处理的算法。可以把二值图划分区域,标出不同的区域编号。只要计算每种编号的个数,就是对应区域的面积了。如果没看懂,不是算法难,是我表达的不好。哈。

2. 将一张图二值化后,有很多连通区域,我想分别求出每一块连通区域的面积,不知道有什么好一点的算法

图像处理里有一种叫做Labeling处理的算法。
可以把二值图划分区域,标出不同的区域编号。
只要计算每种编号的个数,就是对应区域的面积了。
如果没看懂,不是算法难,是我表达的不好。哈。

3. java代码怎么实现计算图像二值连通区域的质心

一:几何距(Geometric
Moments)知识与质心寻找原理
1.
Image
Moments是图像处理中非常有用的算法,可以用来计算区域图像的质心,方向等几何特性,同时Mpq的高阶具有旋转不变性,可以用来实现图像比较分类,正是因为Moments有这些特性,很多手绘油画效果也会基于该算法来模拟实现。它的数学表达为:
它的低阶M00,M01,
M10可以用来计算质心,中心化以后M11,M02,M20可以用来计算区域的方向/角度
2.
什么是质心
就是通过该点,区域达到一种质量上的平衡状态,可能物理学上讲的比较多,简单点的说就是规则几何物体的中心,不规则的可以通过挂绳子的方法来寻找。
二:算法流程
1.
输入图像转换为二值图像
2.
通过连通组件标记算法找到所有的连通区域,并分别标记
3.
对每个连通区域运用计算几何距算法得到质心
4.
用不同颜色绘制连通区域与质心,输出处理后图像
三:算法效果
左边为原图,
右边蓝色为连通组件标记算法处理以后结果,白色点为质心
四:关键代码解析
1.
计算几何距算法代码
doublem00
=
moments(pixels,
width,
height,
0,
0);
doublexCr
=
moments(pixels,
width,
height,
1,
0)
/
m00;//
row
doubleyCr
=
moments(pixels,
width,
height,
0,
1)
/
m00;//
column
return
new
double[]{xCr,
yCr};

4. 谁能给个好用的连通域处理的算法,要8邻域的

楼主要处理的图像是什么样的?黑白图像还是彩色的?我这里有个以前用过的只针对黑白图像的连通域处理,目标是白色,背景是黑色的,不过,如果你的图像不是这样的,那先二值化,然后变换为黑色背景白色目标的图片 CodeGo.net,再调用我这个函数,先看懂我这个函数,然后修改为可以处理白色背景黑色目标 具体函数
其中THRESHOLD_JOINNUM 是个宏定义……
你要先把图像的边缘像素处理下,把边缘1到2个像素宽度的位置,都置为背景色,否则,可能得不到正确的结果,也可能造成访问越界。也就是把四周的边缘像素都置为背景色 然后,如果你仔细看这个函数的实现的话,其实是使用两次连通域处理,一次是用来把黑色的小区域变为白色,也就是填补目标区域中可能出现的小黑洞。然后第二次处理才是用来删除那些小于阈值的白色目标小连通域 这个函数你要看明白才能正确使用。看吧。
2. 楼主要处理的图像是什么样的?黑白图像还是彩色的?我这里有个以前用过的只针对黑白图像的连通域处理,目标是白色,背景是黑色的,不过,如果你的图像不是这样的,那先二值化,然后变换为黑色背景白色目标的图片,再调用我这个函数,先看懂我这个函数,然后修改为可以处理白色背景黑色目标 具体函数

5. connected component是什么意思

connected component
英[kəˈnektɪd kəmˈpəunənt]
美[kəˈnɛktɪd kəmˈponənt]
连通分支[量];
[例句]The crux of the algorithm comes in determining whether a node is the root of a strongly connected component.
算法的关键是判断一个结点是否是强连通分量的根。

6. 怎么把连通区域标记的坐标求出来

你可以试试按照计算物体质心的方法计算:
就是求一个连通区域所有点的坐标平均值,比如第一行的就是X
=
(186+187)/2;
Y
=(5+5)/2;

7. 简述边界表示的四连通区域的种子填充算法的基本思想和执行步骤

一、种子填充算法思想:
首先填充种子所在的尚未填充的一区段,然后确定与这一区段相邻的上下两条扫描线上位于该区段内是否存在需要填充的新区段,如果存在,则依次把每个新区段最右端的象素作为种子放入堆栈。反复这个过程,直到堆栈为空。
二、种子填充算法步骤:
1、初始化堆栈。
2、种子压入堆栈。
3、While(堆栈非空)从堆栈弹出种子象素。

8. 如何判断一个区域是否是连通的 matlab

matlab函数_连通区域

1、 matlab函数bwareaopen──删除小面积对象
格式:BW2 = bwareaopen(BW,P,conn)
作用:删除二值图像BW中面积小于P的对象,默认情况下使用8邻域。
算法:
(1)Determine the connected components.
L = bwlabeln(BW, conn);
(2)Compute the area of each component.
S = regionprops(L, 'Area');
(3)Remove small objects.
bw2 = ismember(L, find([S.Area] >= P));

2、matlab函数bwarea──计算对象面积
格式:total = bwarea(BW)
作用:估计二值图像中对象的面积。
注:该面积和二值图像中对象的像素数目不一定相等。

3、matlab函数imclearborder──边界对象抑制
格式:IM2 = imclearborder(IM,conn)
作用:抑制和图像边界相连的亮对象。若IM是二值图,imclearborder将删除和图像边界相连的对象。默认情况conn=8。
注:For grayscale images, imclearborder tends to rece the overall intensity level in addition to suppressing border structures.
算法:
(1)Mask image is the input image.
(2)Marker image is zero everywhere except along the border, where it equals the mask image.

4、matlab函数bwboundaries──获取对象轮廓
格式:B = bwboundaries(BW,conn)(基本格式)
作用:获取二值图中对象的轮廓,和OpenCV中cvFindContours函数功能类似。B是一个P×1的cell数组,P为对象个数,每个cell 是Q×2的矩阵,对应于对象轮廓像素的坐标。

5、matlab函数imregionalmin──获取极小值区域
格式:BW = imregionalmin(I,conn)
作用:寻找图像I的极小值区域(regional maxima),默认情况conn=8。
Regional minima are connected components of pixels with a constant intensity value, and whose external boundary pixels all have a higher value.

6、matlab函数bwulterode──距离变换的极大值
格式:BW2 = bwulterode(BW,method,conn)
作用:终极腐蚀。寻找二值图像BW的距离变换图的区域极大值(regional maxima)。用于距离变换的距离默认为euclidean,连通性为8邻域。

7、regionprops统计被标记的区域的面积分布,显示区域总数。
函数regionprops语法规则为:STATS = regionprops(L,properties)
该函数用来测量标注矩阵L中每一个标注区域的一系列属性。
L中不同的正整数元素对应不同的区域,例如:L中等于整数1的元素对应区域1;L中等于整数2的元素对应区域2;以此类推。

返回值STATS是一个 长度为max(L(:))的结构数组,结构数组的相应域定义了每一个区域相应属性下的度量。

Properties可以是由逗号分割的字符串行表、包含字符 串的单元数组、单个字符串'all'或者'basic'。如果properties等于字符串'all',则表4.1中的度量数据都将被计算;如果properties等于字符串'basic',则属性:'Area','Centroid'和'BoundingBox'将被计算。表1就是所有有效的属性字符串。

表1 属性字符串行表----度量图像区域的属性或功能
'Area' 图像各个区域中像素总个数
'BoundingBox' 包含相应区域的最小矩形
'Centroid' 每个区域的质心(重心)
'MajorAxisLength' 与区域具有相同标准二阶中心矩的椭圆的长轴长度(像素意义下)
'MinorAxisLength' 与区域具有相同标准二阶中心矩的椭圆的短轴长度(像素意义下)
'Eccentricity' 与区域具有相同标准二阶中心矩的椭圆的离心率(可作为特征)
'Orientation' 与区域具有相同标准二阶中心矩的椭圆的长轴与x轴的交角(度)
'Image' 与某区域具有相同大小的逻辑矩阵
'FilledImage' 与某区域具有相同大小的填充逻辑矩阵
'FilledArea' 填充区域图像中的on像素个数
'ConvexHull' 包含某区域的最小凸多边形
'ConvexImage' 画出上述区域最小凸多边形
'ConvexArea' 填充区域凸多边形图像中的on像素个数
'EulerNumber' 几何拓扑中的一个拓扑不变量——欧拉数
'Extrema' 八方向区域极值点
'EquivDiameter' 与区域具有相同面积的圆的直径
'Solidity' 同时在区域和其最小凸多边形中的像素比例
'Extent' 同时在区域和其最小边界矩形中的像素比例
'PixelIdxList' 存储区域像素的索引下标
'PixelList' 存储上述索引对应的像素坐标

9. 怎么标记二值图连通区域matlab

1)imread把图片读进去2)设定黑白的标准大于0.5的认为是白色,小于0.5的认为是黑色;将读进去的图片转化为只含01的矩阵。3)从上往下一行行的检测,发现某一行存在1,就记录这一行;然后继续检测,直到某一行中没有1,再记录没有1的这一行。4)同理,从左往右一列列检测,记录出现1的列,和不再出现1的列。5)根据3)和4)就可以确定矩阵的边界了,用比它大一圈像素标注一下就好了。ps:如何检测一行存在1;比如矩阵A 的i行。if any(A(i,:)==1)

10. opencv如何标记连通区域 并且提取连通区域

代码

1)Two-pass算法的一种实现
说明:
基于OpenCV和C++实现,领域:4-领域。实现与算法描述稍有差别(具体为记录具有相等关系的label方法实现上)。

// Connected Component Analysis/Labeling By Two-Pass Algorithm
// Author: www.icvpr.com
// Blog : http://blog.csdn.net/icvpr
#include <iostream>
#include <string>
#include <list>
#include <vector>
#include <map>

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

void icvprCcaByTwoPass(const cv::Mat& _binImg, cv::Mat& _lableImg)
{
// connected component analysis (4-component)
// use two-pass algorithm
// 1. first pass: label each foreground pixel with a label
// 2. second pass: visit each labeled pixel and merge neighbor labels
//
// foreground pixel: _binImg(x,y) = 1
// background pixel: _binImg(x,y) = 0

if (_binImg.empty() ||
_binImg.type() != CV_8UC1)
{
return ;
}

// 1. first pass

_lableImg.release() ;
_binImg.convertTo(_lableImg, CV_32SC1) ;

int label = 1 ; // start by 2
std::vector<int> labelSet ;
labelSet.push_back(0) ; // background: 0
labelSet.push_back(1) ; // foreground: 1

int rows = _binImg.rows - 1 ;
int cols = _binImg.cols - 1 ;
for (int i = 1; i < rows; i++)
{
int* data_preRow = _lableImg.ptr<int>(i-1) ;
int* data_curRow = _lableImg.ptr<int>(i) ;
for (int j = 1; j < cols; j++)
{
if (data_curRow[j] == 1)
{
std::vector<int> neighborLabels ;
neighborLabels.reserve(2) ;
int leftPixel = data_curRow[j-1] ;
int upPixel = data_preRow[j] ;
if ( leftPixel > 1)
{
neighborLabels.push_back(leftPixel) ;
}
if (upPixel > 1)
{
neighborLabels.push_back(upPixel) ;
}

if (neighborLabels.empty())
{
labelSet.push_back(++label) ; // assign to a new label
data_curRow[j] = label ;
labelSet[label] = label ;
}
else
{
std::sort(neighborLabels.begin(), neighborLabels.end()) ;
int smallestLabel = neighborLabels[0] ;
data_curRow[j] = smallestLabel ;

// save equivalence
for (size_t k = 1; k < neighborLabels.size(); k++)
{
int tempLabel = neighborLabels[k] ;
int& oldSmallestLabel = labelSet[tempLabel] ;
if (oldSmallestLabel > smallestLabel)
{
labelSet[oldSmallestLabel] = smallestLabel ;
oldSmallestLabel = smallestLabel ;
}
else if (oldSmallestLabel < smallestLabel)
{
labelSet[smallestLabel] = oldSmallestLabel ;
}
}
}
}
}
}

// update equivalent labels
// assigned with the smallest label in each equivalent label set
for (size_t i = 2; i < labelSet.size(); i++)
{
int curLabel = labelSet[i] ;
int preLabel = labelSet[curLabel] ;
while (preLabel != curLabel)
{
curLabel = preLabel ;
preLabel = labelSet[preLabel] ;
}
labelSet[i] = curLabel ;
}

// 2. second pass
for (int i = 0; i < rows; i++)
{
int* data = _lableImg.ptr<int>(i) ;
for (int j = 0; j < cols; j++)
{
int& pixelLabel = data[j] ;
pixelLabel = labelSet[pixelLabel] ;
}
}
}

2)Seed-Filling种子填充方法
说明:
基于OpenCV和C++实现;领域:4-领域。

// Connected Component Analysis/Labeling By Seed-Filling Algorithm
// Author: www.icvpr.com
// Blog : http://blog.csdn.net/icvpr
#include <iostream>
#include <string>
#include <list>
#include <vector>
#include <map>
#include <stack>

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

void icvprCcaBySeedFill(const cv::Mat& _binImg, cv::Mat& _lableImg)
{
// connected component analysis (4-component)
// use seed filling algorithm
// 1. begin with a foreground pixel and push its foreground neighbors into a stack;
// 2. pop the top pixel on the stack and label it with the same label until the stack is empty
//
// foreground pixel: _binImg(x,y) = 1
// background pixel: _binImg(x,y) = 0

if (_binImg.empty() ||
_binImg.type() != CV_8UC1)
{
return ;
}

_lableImg.release() ;
_binImg.convertTo(_lableImg, CV_32SC1) ;

int label = 1 ; // start by 2

int rows = _binImg.rows - 1 ;
int cols = _binImg.cols - 1 ;
for (int i = 1; i < rows-1; i++)
{
int* data= _lableImg.ptr<int>(i) ;
for (int j = 1; j < cols-1; j++)
{
if (data[j] == 1)
{
std::stack<std::pair<int,int>> neighborPixels ;
neighborPixels.push(std::pair<int,int>(i,j)) ; // pixel position: <i,j>
++label ; // begin with a new label
while (!neighborPixels.empty())
{
// get the top pixel on the stack and label it with the same label
std::pair<int,int> curPixel = neighborPixels.top() ;
int curX = curPixel.first ;
int curY = curPixel.second ;
_lableImg.at<int>(curX, curY) = label ;

// pop the top pixel
neighborPixels.pop() ;

// push the 4-neighbors (foreground pixels)
if (_lableImg.at<int>(curX, curY-1) == 1)
{// left pixel
neighborPixels.push(std::pair<int,int>(curX, curY-1)) ;
}
if (_lableImg.at<int>(curX, curY+1) == 1)
{// right pixel
neighborPixels.push(std::pair<int,int>(curX, curY+1)) ;
}
if (_lableImg.at<int>(curX-1, curY) == 1)
{// up pixel
neighborPixels.push(std::pair<int,int>(curX-1, curY)) ;
}
if (_lableImg.at<int>(curX+1, curY) == 1)
{// down pixel
neighborPixels.push(std::pair<int,int>(curX+1, curY)) ;
}
}
}
}
}
}

3)颜色标记(用于显示)

// Connected Component Analysis/Labeling -- Color Labeling
// Author: www.icvpr.com
// Blog : http://blog.csdn.net/icvpr
#include <iostream>
#include <string>
#include <list>
#include <vector>
#include <map>
#include <stack>

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

cv::Scalar icvprGetRandomColor()
{
uchar r = 255 * (rand()/(1.0 + RAND_MAX));
uchar g = 255 * (rand()/(1.0 + RAND_MAX));
uchar b = 255 * (rand()/(1.0 + RAND_MAX));
return cv::Scalar(b,g,r) ;
}

void icvprLabelColor(const cv::Mat& _labelImg, cv::Mat& _colorLabelImg)
{
if (_labelImg.empty() ||
_labelImg.type() != CV_32SC1)
{
return ;
}

std::map<int, cv::Scalar> colors ;

int rows = _labelImg.rows ;
int cols = _labelImg.cols ;

_colorLabelImg.release() ;
_colorLabelImg.create(rows, cols, CV_8UC3) ;
_colorLabelImg = cv::Scalar::all(0) ;

for (int i = 0; i < rows; i++)
{
const int* data_src = (int*)_labelImg.ptr<int>(i) ;
uchar* data_dst = _colorLabelImg.ptr<uchar>(i) ;
for (int j = 0; j < cols; j++)
{
int pixelValue = data_src[j] ;
if (pixelValue > 1)
{
if (colors.count(pixelValue) <= 0)
{
colors[pixelValue] = icvprGetRandomColor() ;
}
cv::Scalar color = colors[pixelValue] ;
*data_dst++ = color[0] ;
*data_dst++ = color[1] ;
*data_dst++ = color[2] ;
}
else
{
data_dst++ ;
data_dst++ ;
data_dst++ ;
}
}
}
}

4)测试程序

// Connected Component Analysis/Labeling -- Test code
// Author: www.icvpr.com
// Blog : http://blog.csdn.net/icvpr
#include <iostream>
#include <string>
#include <list>
#include <vector>
#include <map>
#include <stack>

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

int main(int argc, char** argv)
{
cv::Mat binImage = cv::imread("../icvpr.com.jpg", 0) ;
cv::threshold(binImage, binImage, 50, 1, CV_THRESH_BINARY_INV) ;

// connected component labeling
cv::Mat labelImg ;
icvprCcaByTwoPass(binImage, labelImg) ;
//icvprCcaBySeedFill(binImage, labelImg) ;

// show result
cv::Mat grayImg ;
labelImg *= 10 ;
labelImg.convertTo(grayImg, CV_8UC1) ;
cv::imshow("labelImg", grayImg) ;

cv::Mat colorLabelImg ;
icvprLabelColor(labelImg, colorLabelImg) ;
cv::imshow("colorImg", colorLabelImg) ;
cv::waitKey(0) ;

return 0 ;
}

热点内容
电脑配置信息被改怎么看到 发布:2024-11-07 01:17:06 浏览:776
linuxgc 发布:2024-11-07 00:51:56 浏览:316
乐视改密码是什么意思 发布:2024-11-07 00:47:07 浏览:486
linux图形界面系统 发布:2024-11-07 00:42:00 浏览:999
群控ip是服务器ip么 发布:2024-11-07 00:39:43 浏览:564
安卓手机上制表app哪个好 发布:2024-11-07 00:28:06 浏览:117
电脑进服务器卡了退不出来怎么办 发布:2024-11-07 00:23:30 浏览:763
安卓哪个型号不卡 发布:2024-11-07 00:19:03 浏览:485
mxml库编译 发布:2024-11-07 00:18:07 浏览:213
dnsdns服务器地址 发布:2024-11-07 00:16:23 浏览:11