OpenCV C++/Obj-C:连接附近的等高线
是否有连接两个(或多个)附近等高线的功能?看看我的输入/输出,你就会明白我的意思 我的代码:OpenCV C++/Obj-C:连接附近的等高线,opencv,contour,Opencv,Contour,是否有连接两个(或多个)附近等高线的功能?看看我的输入/输出,你就会明白我的意思 我的代码: [... some processing ...] // getting contours std::vector<std::vector<cv::Point> > contours; findContours(input, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); // approximate contours
[... some processing ...]
// getting contours
std::vector<std::vector<cv::Point> > contours;
findContours(input, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
// approximate contours
std::vector<std::vector<cv::Point> > contours_poly( contours.size() );
for( int i = 0; i < contours.size(); i++ ) {
approxPolyDP(cv::Mat(contours[i]), contours_poly[i], 5, true );
}
// debugging
cv::Scalar colors[3];
colors[0] = cv::Scalar(255, 0, 0);
colors[1] = cv::Scalar(0, 255, 0);
colors[2] = cv::Scalar(0, 0, 255);
for (int idx = 0; idx < contours_poly.size(); idx++) {
cv::drawContours(output, contours_poly, idx, colors[idx % 3]);
}
[…一些处理…]
//获取轮廓
矢量轮廓;
findContours(输入、轮廓、CV_RETR_外部、CV_链_近似_简单);
//近似等高线
std::vector contours_poly(contours.size());
对于(int i=0;i
只需通过点,找到最近的起点或终点,然后连接它们。在您的情况下,很难决定轮廓是否应该连接。如果阿德里安·波波维奇(Adrian Popovici)所说的病态学没有帮助,你必须指定一些最大距离来决定点是否要连接。我想出了这个解决方案,因为我只需要整个对象周围的边界框:
[... some processing ...]
// getting contours
std::vector<std::vector<cv::Point> > contours;
findContours(input, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
// approximate contours
std::vector<std::vector<cv::Point> > contours_poly( contours.size() );
for( int i = 0; i < contours.size(); i++ ) {
approxPolyDP(cv::Mat(contours[i]), contours_poly[i], 5, true );
}
// merge all contours into one vector
std::vector<cv::Point> merged_contour_points;
for (int i = 0; i < contours_poly.size(); i++) {
for (int j = 0; j < contours_poly[i].size(); j++) {
merged_contour_points.push_back(contours_poly[i][j]);
}
}
// get rotated bounding box
std::vector<cv::Point> hull;
cv::convexHull(cv::Mat(merged_contour_points),hull);
cv::Mat hull_points(hull);
cv::RotatedRect rotated_bounding_rect = minAreaRect(hull_points);
[…一些处理…]
//获取轮廓
矢量轮廓;
findContours(输入、轮廓、CV_RETR_外部、CV_链_近似_简单);
//近似等高线
std::vector contours_poly(contours.size());
对于(int i=0;i
有时,消除胡椒噪声可以获得更好的效果:
void removePepperNoise(cv::Mat &mask)
{
for ( int y=2; y<mask.rows-2; y++ ) {
uchar *pUp2 = mask.ptr(y-2);
uchar *pUp1 = mask.ptr(y-1);
uchar *pThis = mask.ptr(y);
uchar *pDown1 = mask.ptr(y+1);
uchar *pDown2 = mask.ptr(y+2);
pThis += 2;
pUp1 += 2;
pUp2 += 2;
pDown1 += 2;
pDown2 += 2;
for (int x=2; x<mask.cols-2; x++) {
uchar value = *pThis; // Get this pixel value (0 or 255). // Check if this is a black pixel that is surrounded by white pixels
if (value == 0) {
bool above, left, below, right, surroundings;
above = *(pUp2 - 2) && *(pUp2 - 1) && *(pUp2) && *(pUp2 + 1) && *(pUp2 + 2);
left = *(pUp1 - 2) && *(pThis - 2) && *(pDown1 - 2);
below = *(pDown2 - 2) && *(pDown2 - 1) && *(pDown2) && *(pDown2 + 1) && *(pDown2 + 2);
right = *(pUp1 + 2) && *(pThis + 2) && *(pDown1 + 2);
surroundings = above && left && below && right;
if (surroundings == true) {
// Fill the whole 5x5 block as white. Since we know
// the 5x5 borders are already white, we just need to
// fill the 3x3 inner region.
*(pUp1 - 1) = 255;
*(pUp1 + 0) = 255;
*(pUp1 + 1) = 255;
*(pThis - 1) = 255;
*(pThis + 0) = 255;
*(pThis + 1) = 255;
*(pDown1 - 1) = 255;
*(pDown1 + 0) = 255;
*(pDown1 + 1) = 255;
// Since we just covered the whole 5x5 block with
// white, we know the next 2 pixels won't be black,
// so skip the next 2 pixels on the right.
pThis += 2;
pUp1 += 2;
pUp2 += 2;
pDown1 += 2;
pDown2 += 2;
}
}
// Move to the next pixel on the right.
pThis++;
pUp1++;
pUp2++;
pDown1++;
pDown2++;
}
}
}
void-removePepperNoise(cv::Mat&mask)
{
对于(int y=2;yy如果曲线足够近,你可以放大图像以使曲线连接起来。你是如何在iOS上执行的?它在iOS上工作。只需在此处获取此OpenCV for iOS版本的副本:并在其周围绕一圈…太棒了。尽可能接受此答案。单击其附近的复选框以选择它作为正式答案。@karlphillip Yep,我会的!我的错,只是一个输入错误…它应该被命名为等高线\u poly
。修复:)你曾经处理过噪音更大或更多断开连接的等高线吗?将所有的等高线合并在一起可能对我的场景不起作用。@dom仅供参考