当前位置: 动力学知识库 > 问答 > 编程问答 >

c++ - opencv - shrink objects to pixels

问题描述:

I am processing such an image as shown in Fig.1, which is composed of an array of points and required to convert to Fig. 2.

Fig.1 original image


Fig.2 wanted image

In order to finish the conversion, firstly I detect the edge of every point and then operate dilation. The result is satisfactory after choosing the proper parameters, seen in Fig. 3.

Fig.3 image after dilation

I processed the same image before in MATLAB. When it comes to shrink objects (in Fig.3) to pixels, function bwmorph(Img,'shrink',Inf) works and the result is exactly where Fig. 2 comes from. So how to get the same wanted image in opencv? It seems that there is no similar shrink function.

Here is my code of finding edge and dilation operation:

#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;

}

网友答案:

1- Find all the contours in your image.

2- Using moments find their center of masses. Example:

/// 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- Create zero(black) image and write all the center points on it.

4- Note that you will have extra one or two points coming from border contours. Maybe you can apply some pre-filtering according to the contour areas, since the border is a big connected contour having large area.

网友答案:

It's not very fast, but I implemented the morphological filtering algorithm from Digital Image Processing, 4th Edition by William K. Pratt. This should be exactly what you're looking for.

The code is MIT licensed and available on GitHub at cgmb/shrink.

Specifically, I've defined cv::Mat cgmb::shrink_max(cv::Mat in) to shrink a given cv::Mat of CV_8UC1 type until no further shrinking can be done.

So, if we compile Shrink.cxx with your program and change your code like so:

#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);

We get this:

By the way, your image revealed a bug in Octave Image's implementation of bwmorph shrink. Figure 2 should not be the result of a shrink operation on Figure 3, as the ring shouldn't be broken by a shrink operation. If that ring disappeared in MATLAB, it presumably also suffers from some sort of similar bug.

At present, Octave and I have slightly different results from MATLAB, but they're pretty close.

分享给朋友:
您可能感兴趣的文章:
随机阅读: