Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.1 original image
Fig.2 wanted 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

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;
}
like image 360
WangYudong Avatar asked Jul 04 '13 07:07

WangYudong


1 Answers

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.

like image 72
baci Avatar answered Sep 19 '22 20:09

baci