제 작품은 도트 배열 (그림 1)이있는 이미지를 기반으로하며, 최종 결과는 그림 4에 나와 있습니다. 단계별로 설명하겠습니다.Opencv : 가장자리 감지, 확장 및 질량계 도면
그림 1 개 원본 이미지
1 단계 :. 내가 더 나은 성능을 위해 삭제하려는 점과 "링"을 포함한 모든 객체의 가장자리를 감지합니다. 그리고 엣지 검출의 결과가 그림 2에 나와 있습니다. 나는 Canny 엣지 디텍터를 사용했으나 일부 밝은 회색 점에서는 잘 작동하지 않았습니다. 첫 번째 질문은 도트의 윤곽을 닫고 가능한 한 다른 노이즈를 줄이는 방법입니다.
도 2 에지 검출
. 단계 2 : 팽창 모든 개체. 나는 구멍을 채우기위한 좋은 방법을 찾지 못했고 그래서 나는 그것들을 직접 넓혔다. 도 3에 도시 된 바와 같이, 홀은 너무 많이 확대되는 것처럼 보이고 다른 노이즈도 증가한다. 두 번째 질문은 구멍을 채우거나 확장하여 구멍을 같은 크기로 채우는 방법입니다.
도 3 팽창 시킴
3 단계 :. 찾아서 각 도트의 질량 중심을 그린다. 도 4에 도시 된 바와 같이, 거친 화상 처리로 인해, "링"의 마크가 존재하고, 몇몇 도트는 2 개의 백색 픽셀로 도시된다. 원하는 결과는 점 하나에 하나의 흰색 픽셀 만 표시해야합니다.
그림 4. 질량 센터
다음은이 3 단계에 대한 나의 코드입니다. 누구든지 내 일을 더 잘하도록 도와 줄 수 있습니까?
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>
#include <cv.h>
#include <highgui.h>
using namespace std;
using namespace cv;
// Global variables
Mat src, edge, dilation;
int dilation_size = 2;
// Function header
void thresh_callback(int, void*);
int main(int argc, char* argv)
{
IplImage* img = cvLoadImage("c:\\dot1.bmp", 0); // dot1.bmp = Fig. 1
// Perform canny edge detection
cvCanny(img, img, 33, 100, 3);
// IplImage to Mat
Mat imgMat(img);
src = img;
namedWindow("Step 1: Edge", CV_WINDOW_AUTOSIZE);
imshow("Step 1: Edge", src);
// Apply the dilation operation
Mat element = getStructuringElement(2, Size(2 * dilation_size + 1, 2 * dilation_size + 1),
Point(dilation_size, dilation_size)); // dilation_type = MORPH_ELLIPSE
dilate(src, dilation, element);
// imwrite("c:\\dot1_dilate.bmp", dilation);
namedWindow("Step 2: Dilation", CV_WINDOW_AUTOSIZE);
imshow("Step 2: Dilation", dilation);
thresh_callback(0, 0);
waitKey(0);
return 0;
}
/* function thresh_callback */
void thresh_callback(int, void*)
{
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
// Find contours
findContours(dilation, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
// Get the 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);
}
// Draw mass centers
Mat drawing = Mat::zeros(dilation.size(), CV_8UC1);
for(int i = 0; i< contours.size(); i++) {
Scalar color = Scalar(255, 255, 255);
line(drawing, mc[i], mc[i], color, 1, 8, 0);
}
namedWindow("Step 3: Mass Centers", CV_WINDOW_AUTOSIZE);
imshow("Step 3: Mass Centers", drawing);
}
[여기] (http://stackoverflow.com/questions/1716274/fill-the-holes-in-opencv)에서 아무 것도 시도하지 않으셨습니까? – William