gpt4 book ai didi

c++ - OpenCV Canny + 分水岭

转载 作者:可可西里 更新时间:2023-11-01 16:39:57 26 4
gpt4 key购买 nike

我正在使用精明的边缘检测和查找轮廓函数(均为 OpenCV)为分水岭变换创建标记。一切正常,但我对结果不是 100% 满意。原因是一些边丢失了,因此丢失了重要信息。更详细地说,我得到了一堆窗口(前 View ),它们是矩形的,在分水岭变换之后我最终得到这样的东西:

enter image description here enter image description here但我宁愿有漂亮的矩形,它们是完整的并且没有向一侧开放。在保持不规则形状(房子前面的灌木丛、汽车......)的同时,我有什么办法可以解决这个问题吗?我考虑过用网格覆盖整个图像,但我做不到。

非常感谢。

这是我的代码:

Mat gray;
cvtColor(im, gray, CV_BGR2GRAY);

// Use Canny instead of threshold to catch squares with gradient shading
Mat bw;
Canny(gray, bw, 0, 100, 5, true);

// Find contours
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;

findContours( bw, contours, hierarchy,
CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );


// watershed
Mat markers(bw.size(), CV_32S);
markers = Scalar::all(0);
int idx = 0;
int compCount = 0;
for( ; idx >= 0; idx = hierarchy[idx][0], compCount++ ) {
if (fabs(contourArea(contours[compCount])) < min_size )
continue;
drawContours(markers, contours, idx, Scalar::all(compCount+1), 1, 8, hierarchy, INT_MAX);
}
watershed( im, markers );

根据要求,这是原始图像,我想要得到的图像和我的输出: enter image description here

我想要这样的分割(虽然过度分割没有坏处,我只需要确保,我得到所有的细节):

enter image description here

虽然我得到这样的东西: enter image description here(请忽略颜色,它们对于这个问题并不重要,只是我整个程序的结果)。这只是一个例子,如果你愿意,我可以给你展示更多,也请看看etrims数据集,我所有的图片都来自那里。

最佳答案

两件事-

1) 如前所述,边缘检测会导致拾取虚假边缘。

2) 使用这些边作为分水岭分割的标记会导致过度分割,因为每个标记都会在输出中产生一个分割区域

策略-

(i) 预处理:对图像进行大量平滑处理(通过重建进行的形态学开运算可用于使强度均匀化,而不会显着影响您感兴趣的边缘)。

(ii) 标记:我不使用边作为种子,而是使用局部极值。理想情况下,我们希望每个要分割的区域都有一个标记。

(iii) 分割:找到步骤 (i) 中图像的梯度大小(范围过滤也是一个不错的选择),并将其用作分割函数。

使用此策略,我得到以下 segmentation 。

enter image description here

或者,在步骤 (i) 之后,您可以使用 Canny 边缘检测并进行一些形态学清理(以填充轮廓并移除剩余的边缘)。这就是我得到的。

enter image description here

这些并不完全是预期的分割(一些物体如汽车没有被检测到),但这是一个好的开始。

编辑:用于生成图像的 MATLAB 代码 -

% convert to grayscale
img = rgb2gray(origImg);

% create an appropriate structuring element
w_size = 20;
seSquare = strel('square', w_size);

% opening by reconstruction - to smooth dark regions
imgEroded = imerode(img, seSquare);
imgRecon = imreconstruct(imgEroded, img);

% invert and repeat - to smooth bright regions
imgReconComp = imcomplement(imgRecon);
imgEroded2 = imerode(imgReconComp, seSquare);
imgRecon2 = imreconstruct(imgEroded2, imgReconComp);

% get foreground markers
fgm = imregionalmax(imgRecon2);

% get background markers - this step can be skipped
% in which case only fgm would be the marker image
% and the segmentation would be different
distTrans = bwdist(fgm);
wLines= watershed(distTrans);
bgm = wLines == 0;

% get the segmentation function and impose markers
% perform watershed segmentation
seSquare3 = strel('square', 3);
rangeImg = rangefilt(imgRecon2, getnhood(seSquare3));
segFunc = imimposemin(rangeImg, fgm | bgm);
grayLabel = watershed(segFunc);

rgbLabel= label2rgb(grayLabel);
figure, imshow(rgbLabel); title('Output using Watershed')

% alternatively, extract edges from the preprocessed image
% perform morph cleanup
bwEdges = edge(imgRecon2, 'canny');
bwFilled = imfill(bwEdges, 'holes');
bwRegions = imopen(bwFilled, seSquare3);
grayLabel = bwlabel(bwRegions);

rgbLabel = label2rgb(grayLabel, 'jet', 'k');
figure, imshow(rgbLabel); title('Output using Canny')

关于c++ - OpenCV Canny + 分水岭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21060804/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com