opencv - 将对象缩小为像素

时间:2013-07-04 07:09:32

标签: c++ opencv image-processing computer-vision

我正在处理如图1所示的图像,它由一系列点组成,需要转换为图2.

图1原始图像

Fig.1 original image
图2想要的图像

Fig.2 wanted image

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

图3扩张后的图像

Fig.3 image after dilation

我在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;
}

2 个答案:

答案 0 :(得分:4)

您图片中的/// 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 ); }

2-使用Find all the contours找到他们的群众中心。例如:

{{1}}

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

4-请注意,您将从边界轮廓中获得额外的一个或两个点。也许您可以根据moments应用一些预过滤,因为边界是一个大面积的大连通轮廓。

答案 1 :(得分:0)

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

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

具体来说,我已定义cv::Mat cgmb::shrink_max(cv::Mat in)缩小给定cv::Mat CV_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);

我们得到了这个:

image after binary shrink

顺便说一句,你的图片显示a bug in Octave Image实现了bwmorph缩小。图2不应该是图3中收缩操作的结果,因为环不应该通过收缩操作来破坏。如果那个环在MATLAB中消失了,它可能也会遇到某种类似的错误。

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