Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在OpenCV 2.4.10中过滤出小轮廓_C++_Opencv_Filter_Contour_Opencv Contour - Fatal编程技术网

C++ 如何在OpenCV 2.4.10中过滤出小轮廓

C++ 如何在OpenCV 2.4.10中过滤出小轮廓,c++,opencv,filter,contour,opencv-contour,C++,Opencv,Filter,Contour,Opencv Contour,快速事实:我对OpenCV非常陌生,但我想用它变得更好,但目前我真的很不擅长(显然没有经验或导师…)。我需要做一个程序,可以检测不同的物体从四架直升机,唯一的问题是我得到吨小随机形状出现。我从这里借用了代码:并在四架直升机拍摄的一些图像上进行了尝试。以下是程序的结果:。它应该只看到顶部附近的银色盒子,但它看到的都是小形状。我从逻辑上知道该做什么;只是如果形状的面积低于某个像素量,就不要在形状周围画线。。。但我不知道怎么做。我稍微修改了代码,并将其包含在下面。我该怎么做呢?(如果您知道任何关于Op

快速事实:我对OpenCV非常陌生,但我想用它变得更好,但目前我真的很不擅长(显然没有经验或导师…)。我需要做一个程序,可以检测不同的物体从四架直升机,唯一的问题是我得到吨小随机形状出现。我从这里借用了代码:并在四架直升机拍摄的一些图像上进行了尝试。以下是程序的结果:。它应该只看到顶部附近的银色盒子,但它看到的都是小形状。我从逻辑上知道该做什么;只是如果形状的面积低于某个像素量,就不要在形状周围画线。。。但我不知道怎么做。我稍微修改了代码,并将其包含在下面。我该怎么做呢?(如果您知道任何关于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;
} 
#包括“opencv2/core/core.hpp”
#包括“opencv2/flann/miniflann.hpp”
#包括“opencv2/imgproc/imgproc.hpp”
#包括“opencv2/photo/photo.hpp”
#包括“opencv2/video/video.hpp”
#包括“opencv2/features2d/features2d.hpp”
#包括“opencv2/objdetect/objdetect.hpp”
#包括“opencv2/calib3d/calib3d.hpp”
#包括“opencv2/ml/ml.hpp”
#包括“opencv2/highgui/highgui.hpp”
#包括“opencv2/contrib/contrib.hpp”
#包括“opencv2/core/core_c.h”
#包括“opencv2/highgui/highgui_c.h”
#包括“opencv2/imgproc/imgproc_c.h”
使用名称空间cv;
使用名称空间std;
int main()
{
IplImage*img=cvLoadImage(“C:/Users/wyndr_000/Documents/visualstudio 2013/Projects/OpenCV2410Test2/OpenCV2410Test2/Testpic2.png”);
//显示原始图像
CVD公司(“原始”);
cvShowImage(“原始”,img);
//将原始图像转换为灰度
IplImage*imgGrayScale=cvCreateImage(cvGetSize(img),8,1);
CVT颜色(img、imgGrayScale、CV_BGR2GRAY);
//对灰度图像进行阈值化以获得更好的结果
cvThreshold(imgGrayScale,imgGrayScale,128,255,CV_THRESH_二进制);
CvSeq*contours;//将指针指向内存块中的轮廓
CvSeq*result;//保留轮廓点的序列
CvMemStorage*storage=cvCreateMemStorage(0);//所有轮廓的存储区域
//查找图像中的所有轮廓
cvFindContours(图像缩放、存储和等高线、尺寸(CvContour)、等高线列表、等高线链近似值、等高线点(0,0));
//迭代通过每个轮廓
while(等高线)
{
//获取由变量“轮廓”指向的轮廓点序列
结果=cvApproxPoly(等高线、尺寸(CvContour)、存储、CV_POLY_近似_DP、CVContourp周长(等高线)*0.02,0);
//如果轮廓中有3个顶点(应为三角形)
如果(结果->总计==3)
{
//迭代通过每个点
CvPoint*pt[3];
对于(int i=0;i<3;i++){
pt[i]=(CvPoint*)cvgetsequelem(结果,i);
}
//在三角形周围画线
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);
}
//如果轮廓中有4个顶点(应为四边形)
否则如果(结果->总计==4)
{
//迭代通过每个点
CvPoint*pt[4];
对于(int i=0;i<4;i++){
pt[i]=(CvPoint*)cvgetsequelem(结果,i);
}
//在四边形周围画线
cvLine(img,*pt[0],*pt[1],cvScalar(0255,0),4);
cvLine(img,*pt[1],*pt[2],cvScalar(0255,0),4);
cvLine(img,*pt[2],*pt[3],cvScalar(0255,0),4);
cvLine(img,*pt[3],*pt[0],cvScalar(0255,0),4);
}
//如果轮廓中有7个顶点(应为七边形)
否则如果(结果->总计==7)
{
//迭代通过每个点
CvPoint*pt[7];
对于(int i=0;i<7;i++){
pt[i]=(CvPoint*)cvgetsequelem(结果,i);
}
//围绕七边形画线
cvLine(img,*pt[0],*pt[1],cvScalar(0,0255),4);
cvLine(img,*pt[1],*pt[2],cvScalar(0,0255),4);
cvLine(img,*pt[2],*pt[3],cvScalar(0,0255),4);
cvLine(img,*pt[3],*pt[4],cvScalar(0,0255),4);
cvLine(img,*pt[4],*pt[5],cvScalar(0,0255),4);
cvLine(img,*pt[5],*pt[6],cvScalar(0,0255),4);
cvLine(img,*pt[6],*pt[0],cvScalar(0,0255),4);
}
//获得下一个轮廓
轮廓=轮廓->h_下一步;
}
//显示标记已识别形状的图像
CVD(“跟踪”);
cvShowImage(“跟踪”,img);
cvWaitKey(0);//等待按键
//清理
cvallwindows();
cvReleaseMemStorage(&storage);
cvReleaseImage(&img);
cvReleaseImage(&imgGrayScale);
返回0;
} 

这里的问题是阈值通过后留下的噪声。这些技术应该能解决你的问题。(特别是打开/关闭图像的部分)

您是否考虑过使用来查找每个轮廓的所有区域,对于低于一定数量的轮廓区域,使用黑色将其归零?我知道有一个函数contourArea,但我不知道如何使用它。我查过了,但我不知道如何在这里使用它。
contourArea
确定封闭轮廓所包围的总面积。它基本上是对轮廓所包含的所有白色像素求和。您所要做的就是找到每个轮廓所包围的所有区域,并过滤掉那些小于规定最小值的区域。