以下是来自MatLab的原始代码:
% Calculate each separated object area
cDist=regionprops(bwImg, 'Area');
cDist=[cDist.Area];
% Label each object
[bwImgLabeled, ~]=bwlabel(bwImg);
% Calculate min and max object size based on assumptions on the color
% checker size
maxLabelSize = prod(size(imageData)./[4 6]);
minLabelSize = prod(size(imageData)./[4 6]./10);
% Find label indices for objects that are too large or too small
remInd = find(cDist > maxLabelSize);
remInd = [remInd find(cDist < minLabelSize)];
% Remove over/undersized objects
for n=1:length(remInd)
ri = bwImgLabeled == remInd(n);
bwImgLabeled(ri) = 0;
以下是我使用OpenCV编写的代码
//regionprops(bwImg, 'Area');
// cDist=[cDist.Area]
//cv::FileStorage file("C:\\Users\\gdarmon\\Desktop\\gili.txt", cv::FileStorage::WRITE);
//
//file << dst;
dst.convertTo(dst,CV_8U);
cv::vector<cv::vector<cv::Point> > contours;
cv::vector<cv::Vec4i> hierarchy;
cv::findContours(dst,contours,hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE);
std::vector<cv::Moments> mu(contours.size());
for (int i = 0; i < contours.size(); i++)
{
mu[i] = cv::moments(contours[i],false);
}
vector<cv::Point2f> mc( contours.size() );
for( int i = 0; i < contours.size(); i++ )
{
mc[i] = cv::Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 );
}
因为现在我有了轮廓,我想使用bwLabel功能
1.我认为做标签是为了连接4-8个对象。你能解释一下什么是贴标签吗?我会指出任何联系。
2.connected components in OpenCV在本文中,有人在谈论CVBlob,也有人在谈论opecv的cvConourArea,你能解释一下这两者的区别吗?什么更适合我的用例?
更新:以下是我尝试使用cvBlobs的方法
IplImage* img_bw = new IplImage(dst);
CBlobResult blobs;
CBlob *currentBlob;
blobs = CBlobResult(img_bw, NULL, 0);
// Exclude all white blobs smaller than the given value (80)
// The bigger the last parameter, the bigger the blobs need
// to be for inclusion
blobs.Filter( blobs,
B_EXCLUDE,
CBlobGetArea(),
B_LESS,
80 );
// Get the number of blobs discovered
int num_blobs = blobs.GetNumBlobs();
// Display the filtered blobs
IplImage* filtered = cvCreateImage( cvGetSize( img_bw ),
IPL_DEPTH_8U,
3 );
cvMerge( img_bw, img_bw, img_bw, NULL, filtered );
for ( int i = 0; i < num_blobs; i++ )
{
currentBlob = blobs.GetBlob( i );
currentBlob->FillBlob( filtered, CV_RGB(255,0,0));
}
// Display the input / output windows and images
cvNamedWindow( "input" );
cvNamedWindow( "output" );
cvShowImage("input", img_bw );
cvShowImage("output", filtered);
cv::waitKey(0);
/*% Calculate min and max object size based on assumptions on the color
% checker size
maxLabelSize = prod(size(imageData)./[4 6]);
minLabelSize = prod(size(imageData)./[4 6]./10);*/
double maxLabelSize = (dst.rows/4.0) * (dst.cols/6.0);
double minLabelSize = ((dst.rows/40.0) * (dst.cols/60.0));
2条答案
按热度按时间w1jd8yoj1#
1.我认为做标签是为了连接4-8个对象。你能解释一下什么是贴标签吗?我会指出任何联系。
标签实际作用的最清楚演示是在
bwlabel
的MatLab文档中。如果将原始矩阵BW
与结果矩阵L
进行比较,您将看到它获取一个二进制图像,并为每个相连的1
组分配唯一的标签:这里有三个标记的组件。本例寻找4连通分量;如果像素位于当前像素的左侧、右侧、上方或下方,则将其视为已连接到当前像素。8-连接的对象包括对角线,这将导致上面的矩阵的标签
2
和3
合并,因为对象2的右下角和对象3的顶部是对角连接的。维基百科here上描述了连通分量标记算法。2.OpenCV中的连接组件在本文中,有人说CVBlob,有人说opecv的cvConourArea,你能解释一下这两者的区别吗?什么更适合我的用例?
OpenCV 3.0还处于测试阶段,它有两个全新的方法:
connectedComponents
和connectedComponentsWithStats
(文档)。如果您正在尝试复制MatLab的bwlabel
,那么这是一条可行的道路。我编写了一个测试程序来试用
connectedComponentsWithStats
(下面的完整代码),并将其用作我的测试映像:(实际上,此图像已从800x600缩小到400x300,但生成它的代码如下所示。)
我使用以下命令生成了标记的图像:
nLabels
中返回的值为5
。请记住,此方法将背景视为标签为0
。要查看标记区域是什么,可以将灰阶值从
[0..nLabels-1]
放大到[0..255]
,或者可以指定随机的RGB值并创建彩色图像。在此测试中,我只打印出了几个位置的值,我知道这些位置位于不同的组件中。stats
是包含每个组件(包括背景)的left, top, width, height, and area
的5 x nLabels
垫。对于此图像:您将注意到组件
0
是图像的全宽/全高。将所有区域相加,得到480,000 = 800x600
。前4个元素可用于创建边界矩形:centroids
是包含每个零部件质心的x, y
坐标的2 x nLabels
材质:最后,在某些情况下,您可能需要单独对其中一个组件进行进一步处理。在这里,我使用
compare
生成一个新的matonly2
,它只包含labels
中标记为2
的像素。compare
有助于在新图像中将这些像素设置为255
的值,以便您可以看到结果:以下是完整的代码:
vsaztqbk2#
我使用了下面的代码,这可能是耗时取决于您的图像大小。