Быстрые факты: я Крайне плохо знаком с OpenCV, но хочу стать лучше с ним, но в настоящее время я действительно плохо с ним (нет опыта или наставника, так очевидно …). Мне нужно создать программу, которая может обнаруживать различные объекты из квадрокоптера, единственная проблема в том, что у меня появляются тонны маленьких случайных фигур. Я позаимствовал код здесь: http://opencv-srf.blogspot.com/2011/09/object-detection-tracking-using-contours.html и попробовал это на некоторых изображениях, снятых с четырехъядерного коптера. Вот результат программы: http://imgur.com/IqzNVVr. Он должен был видеть только серебристую коробочку в верхней части, но есть все маленькие формы, которые он видит. Я логично знаю, что делать; просто не рисуйте линии вокруг фигуры, если ее площадь меньше определенного количества пикселей … но я понятия не имею, как это сделать. Я немного изменил код и включил его ниже. Как бы я поступил так? (также, если вы знаете какие-нибудь хорошие подробные руководства для OpenCV, это было бы здорово!)
Код:
#include "opencv2/core/core.hpp"#include "opencv2/flann/miniflann.hpp"#include "opencv2/imgproc/imgproc.hpp"#include "opencv2/photo/photo.hpp"#include "opencv2/video/video.hpp"#include "opencv2/features2d/features2d.hpp"#include "opencv2/objdetect/objdetect.hpp"#include "opencv2/calib3d/calib3d.hpp"#include "opencv2/ml/ml.hpp"#include "opencv2/highgui/highgui.hpp"#include "opencv2/contrib/contrib.hpp"#include "opencv2/core/core_c.h"#include "opencv2/highgui/highgui_c.h"#include "opencv2/imgproc/imgproc_c.h"
using namespace cv;
using namespace std;
int main()
{
IplImage* img = cvLoadImage("C:/Users/wyndr_000/Documents/Visual Studio 2013/Projects/OpenCV2410Test2/OpenCV2410Test2/Testpic2.png");
//show the original image
cvNamedWindow("Raw");
cvShowImage("Raw", img);
//converting the original image into grayscale
IplImage* imgGrayScale = cvCreateImage(cvGetSize(img), 8, 1);
cvCvtColor(img, imgGrayScale, CV_BGR2GRAY);
//thresholding the grayscale image to get better results
cvThreshold(imgGrayScale, imgGrayScale, 128, 255, CV_THRESH_BINARY);
CvSeq* contours; //hold the pointer to a contour in the memory block
CvSeq* result; //hold sequence of points of a contour
CvMemStorage *storage = cvCreateMemStorage(0); //storage area for all contours
//finding all contours in the image
cvFindContours(imgGrayScale, storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0, 0));
//iterating through each contour
while (contours)
{
//obtain a sequence of points of contour, pointed by the variable 'contour'
result = cvApproxPoly(contours, sizeof(CvContour), storage, CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.02, 0);//if there are 3 vertices in the contour(It should be a triangle)
if (result->total == 3)
{
//iterating through each point
CvPoint *pt[3];
for (int i = 0; i < 3; i++){
pt[i] = (CvPoint*)cvGetSeqElem(result, i);
}
//drawing lines around the triangle
cvLine(img, *pt[0], *pt[1], cvScalar(255, 0, 0), 4);
cvLine(img, *pt[1], *pt[2], cvScalar(255, 0, 0), 4);
cvLine(img, *pt[2], *pt[0], cvScalar(255, 0, 0), 4);
}
//if there are 4 vertices in the contour(It should be a quadrilateral)
else if (result->total == 4)
{
//iterating through each point
CvPoint *pt[4];
for (int i = 0; i < 4; i++){
pt[i] = (CvPoint*)cvGetSeqElem(result, i);
}
//drawing lines around the quadrilateral
cvLine(img, *pt[0], *pt[1], cvScalar(0, 255, 0), 4);
cvLine(img, *pt[1], *pt[2], cvScalar(0, 255, 0), 4);
cvLine(img, *pt[2], *pt[3], cvScalar(0, 255, 0), 4);
cvLine(img, *pt[3], *pt[0], cvScalar(0, 255, 0), 4);
}
//if there are 7 vertices in the contour(It should be a heptagon)
else if (result->total == 7)
{
//iterating through each point
CvPoint *pt[7];
for (int i = 0; i < 7; i++){
pt[i] = (CvPoint*)cvGetSeqElem(result, i);
}
//drawing lines around the heptagon
cvLine(img, *pt[0], *pt[1], cvScalar(0, 0, 255), 4);
cvLine(img, *pt[1], *pt[2], cvScalar(0, 0, 255), 4);
cvLine(img, *pt[2], *pt[3], cvScalar(0, 0, 255), 4);
cvLine(img, *pt[3], *pt[4], cvScalar(0, 0, 255), 4);
cvLine(img, *pt[4], *pt[5], cvScalar(0, 0, 255), 4);
cvLine(img, *pt[5], *pt[6], cvScalar(0, 0, 255), 4);
cvLine(img, *pt[6], *pt[0], cvScalar(0, 0, 255), 4);
}
//obtain the next contour
contours = contours->h_next;
}//show the image in which identified shapes are marked
cvNamedWindow("Tracked");
cvShowImage("Tracked", img);
cvWaitKey(0); //wait for a key press
//cleaning up
cvDestroyAllWindows();
cvReleaseMemStorage(&storage);
cvReleaseImage(&img);
cvReleaseImage(&imgGrayScale);
return 0;
}
Проблема здесь в том, что после прохождения порога остается шум. Методы описано здесь должен решить вашу проблему. (В частности, часть, посвященная открытию / закрытию изображения)