Mon travail est basé sur des images avec un tableau de points (Fig. 1), et le résultat final est montré sur la Fig. 4. Je vais expliquer mon travail pas à pas.Opencv: Détection de contours, Dilatation et Dessin de compteur de masse
Figure 1 Image originale
Étape 1:. détecter le bord de chaque objet, y compris les points et un "anneau" que je veux supprimer pour une meilleure performance. Et le résultat de la détection de bord est représenté sur la Fig.2. J'ai utilisé le détecteur de bord Canny mais il ne marchait pas bien avec quelques points gris clair. Ma première question est de savoir comment fermer les contours des points et réduire autant que possible les autres bruits?
figure 2 Détection des bords
Etape 2:. de Dilate chaque objet. Je n'ai pas trouvé un bon moyen de remplir les trous, donc je les dilate directement. Comme le montre la figure 3, les trous semblent être trop élargis, de même que les autres bruits. Ma deuxième question est comment remplir ou dilater les trous afin de les faire remplir des cercles de la même taille?
figure 3 Dilatation
Étape 3:. Trouver et établir le centre de masse de chaque point. Comme le montre la figure 4, en raison du traitement d'image grossier, il existe une marque de «l'anneau» et certains points sont représentés en deux pixels blancs. Le résultat recherché ne doit montrer que les points et un pixel blanc pour un point.
Fig. 4: centres de masse
Voici mon code pour ces 3 étapes. Quelqu'un peut-il aider à améliorer mon travail?
#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);
}
Avez-vous déjà essayé quelque chose de [ici] (http://stackoverflow.com/questions/1716274/fill-the-holes-in-opencv)? – William