2015-04-08 7 views
0

Краткие факты: Я EXTREMELY новичок в OpenCV, но хочу стать лучше с ним, но в настоящее время я действительно плохо с ним (нет опыта или наставника, так очевидно ...). Мне нужно сделать программу, которая может обнаружить различные объекты из квадроцикла, только проблема в том, что я получаю тонны маленьких случайных фигур. Я заимствовал код отсюда: http://opencv-srf.blogspot.com/2011/09/object-detection-tracking-using-contours.html и попробовал его на некоторых изображениях, взятых из четырехместного вертолета. Вот результат программы: http://imgur.com/IqzNVVr. Он должен был видеть только серебряную коробку у вершины, но есть все маленькие фигуры, которые она видит. Я знаю логично, что делать; просто не рисуйте линии вокруг формы, если ее площадь ниже определенного количества пикселей ... но я не знаю, как это сделать. Я немного изменил кодировку и включил ее ниже. Как мне это сделать? (Также, если вы знаете какие-нибудь хорошие учебники углубленных для OpenCV, что было бы здорово!)Как отфильтровать небольшие контуры в OpenCV 2.4.10

Код:

#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; 
} 
+0

Вы рассмотрели использование ['contourArea'] (http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html#contourarea), чтобы найти все области каждого контура и для любой области контура, которая ниже определенной величины, используйте ['drawContours'] (http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html#drawcontours) в черном цвете их обнулить? – rayryeng

+0

Я знаю, что есть функция contourArea, но я не понимаю, как ее использовать. Я искал его, но я не понимаю, как его использовать. – Wyndrix

+0

'contourArea' определяет общую площадь, ограниченную замкнутым контуром. Это, в основном, суммирование всех белых пикселей, окружающих контур. Все, что вам нужно сделать, это найти все области, ограниченные каждым контуром, и отфильтровать те, которые меньше заданного минимума. – rayryeng

ответ

0

Вопрос здесь шум остается после порогового прохода. Методы described here должны решить вашу проблему. (В частности, часть на открытии/закрытии изображения)

Смежные вопросы