6

我正在处理如图 1 所示的图像,该图像由点数组组成,需要转换为图 2。

图1 原图

图1 原图
Fig.2 想要的图像

Fig.2 想要的图像

为了完成转换,我首先检测edge每个点的 ,然后操作dilation。选择合适的参数后,结果令人满意,如图 3 所示。

图3 膨胀后的图像

图3 膨胀后的图像

我之前在 MATLAB 中处理过相同的图像。当将对象(图 3 中)缩小为像素时,函数bwmorph(Img,'shrink',Inf)起作用,结果正是图 2 的来源。那么如何在opencv中获得相同的想要的图像呢?好像没有类似的shrink功能。

这是我查找边缘和膨胀操作的代码:

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>
#include <cv.h>
#include <highgui.h>
using namespace cv;

// Global variables
Mat src, dilation_dst;
int dilation_size = 2;

int main(int argc, char *argv[])
{
    IplImage* img = cvLoadImage("c:\\001a.bmp", 0);                 // 001a.bmp is Fig.1                              

    // Perform canny edge detection
    cvCanny(img, img, 33, 100, 3);

    // IplImage to Mat
    Mat imgMat(img);
    src = img;

    // Create windows
    namedWindow("Dilation Demo", CV_WINDOW_AUTOSIZE);

    Mat element = getStructuringElement(2,                          // dilation_type = MORPH_ELLIPSE
                  Size(2*dilation_size + 1, 2*dilation_size + 1),
                  Point(dilation_size, dilation_size));

    // Apply the dilation operation
    dilate(src, dilation_dst, element);
    imwrite("c:\\001a_dilate.bmp", dilation_dst);
    imshow("Dilation Demo", dilation_dst);

    waitKey(0);
    return 0;
}
4

2 回答 2

4

1-找到图像中的所有轮廓。

2-使用找到它们的质心。例子:

/// Get moments
vector<Moments> mu(contours.size() );
for( int i = 0; i < contours.size(); i++ )
{ mu[i] = moments( contours[i], false ); }

/// Get the mass centers:
vector<Point2f> mc( contours.size() );
for( int i = 0; i < contours.size(); i++ )
{ mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 ); }

3- 创建零(黑色)图像并在其上写入所有中心点。

4- 请注意,您将有来自边界轮廓的额外一两个点。也许你可以根据轮廓区域应用一些预过滤,因为边界是一个大面积的连接轮廓。

于 2013-07-04T07:24:47.263 回答
0

它不是很快,但我实现了来自William K. Pratt的Digital Image Processing, 4th Edition的形态滤波算法。这应该正是您正在寻找的。

该代码已获得 MIT 许可,可在 GitHub 上的cgmb/shrink获得。

具体来说,我已经定义cv::Mat cgmb::shrink_max(cv::Mat in)收缩给定cv::MatCV_8UC1类型,直到无法进一步收缩。

所以,如果我们用你的程序编译Shrink.cxx并像这样改变你的代码:

#include "Shrink.h" // add this line
...
dilate(src, dilation_dst, element);
dilation_dst = cgmb::shrink_max(dilation_dst); // and this line
imwrite("c:\\001a_dilate.bmp", dilation_dst);

我们得到这个:

二进制收缩后的图像

顺便说一句,您的图像揭示了 Octave Image的 bwmorph 收缩实现中的一个错误。图 2 不应该是图 3 中收缩操作的结果,因为环不应该被收缩操作破坏。如果那个环在 MATLAB 中消失了,它大概也遭受了某种类似的错误。

目前,Octave 和我从 MATLAB 得到的结果略有不同,但它们非常接近。

于 2015-03-24T00:02:27.983 回答