c++ - 使用 C++ FindContours 在视频图像中查找轮廓的问题

标签 c++ image-processing opencv video-processing contour

我现在正在处理的程序差不多 完成了,但我对结果不是很满意。通过使用 Canny 算法,我设法非常清楚地了解了对象的轮廓,但是程序在识别轮廓和用红线绘制轮廓时遇到了一些问题。程序:

void setwindowSettings(){
    namedWindow("Contours", CV_WINDOW_AUTOSIZE);

    createTrackbar("LowerC", "Contours", &lowerC, 255, NULL);
    createTrackbar("UpperC", "Contours", &upperC, 255, NULL);
}

void wait(void)
{
    long t=30000000;
    while(t--);
}

int main(void)
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened())  // check if we succeeded
    return -1;

Mat frame,foreground,image;
double pt1, pt2, area;
Rect rect;
int i;

vector<vector<Point> > contours;
vector<vector<Point> > largest_contours;

namedWindow("Capture", CV_WINDOW_AUTOSIZE);
setwindowSettings();

while(1){
    cap >> frame; // get a new frame from camera
    if( frame.empty() )
            break;
    image=frame.clone();

    cvtColor(image,foreground,CV_BGR2GRAY);
    GaussianBlur(foreground,foreground,Size(9,11),0,0);
    Canny(foreground,foreground,lowerC,upperC,3);

    findContours(foreground,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE);  

    if(contours.empty())
        continue;

    double largest_area = 0;

    for( i= 0; i < contours.size(); i++){  // get the largest contour
        area = fabs(contourArea(contours[i]));
        if(area >= largest_area){
            largest_area = area;
            largest_contours.clear(); 
            largest_contours.push_back(contours[i]);
        }
    }

    if(largest_area>=3000){   // draw the largest contour if exceeded minimum largest area 
        drawContours(image,largest_contours,-1,Scalar(0,0,255),2);
        printf("area = %.f\n",largest_area);
    }

    wait();

    imshow( "Capture",image );
    imshow("Contours",foreground);

    if(waitKey(30) >= 0) break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}

程序摘要:

  1. 从相机获取图像
  2. 噪声过滤(转换为灰色 → 模糊 → Canny)
  3. 寻找轮廓
  4. 找到图像中最大的轮廓及其面积,也就是物体
  5. 在物体周围画一条红线并打印出最大的区域
  6. 冲洗并重复

结果:

我很少得到我想要的;检测到轮廓,绘制红线(GOOD ONE):

Contours detected. Noted that half the contour line disappears

...通常我会得到这个;未检测到轮廓,不是红线(BAD ONE):

No contour detected, although there is a contour

获得GOOD ONE的机会大约是1/20这不是很好。此外,对象轮廓线在 Contours 中当物体周围出现红线时,屏幕将闪烁(参见 GOOD ONE 图片)。 我正在使用我的一个物体(一个黑色的小方框)来回答这个问题,但请注意,这个物体检测程序的主要目标是检测物体而不考虑其形状或颜色。

所以我的问题是:

  1. 为什么轮廓清晰如初,我还是得到了 BAD ONES?
  2. 谁能分享关于如何改进轮廓检测的更好想法? (即更好的模糊算法)
  3. 在对象周围画红线时,如何避免轮廓线闪烁?

编辑: 我刚刚发现轮廓线闪烁不是因为它周围画了红线(使用 drawContoursline 函数),而是在检测到最大轮廓线之后发生通过 findContours函数并计算为最大轮廓。

关于没有的问题。 3 点击 HERE . VIDEO HERE, CLICK IT!!!

提前致谢。

PS:我在 Ms Visual C++ 2010 Exp 上使用 OpenCV 2.4.3。

最佳答案

  1. 由于您使用的是最大轮廓这一事实,所以我假设您正在尝试检测出现在相机视野中的最大物体。我想知道为什么右上角的窗光/明亮光源没有产生任何轮廓(可能是由于模糊)。您可以存储背景图像并从对象出现的图像中减去它。这样您就可以导出对象。您可以在差异图像中应用轮廓查找。 absdiff(frame_now,frame_backgrnd,diff)其中 diff是差异图像。
  2. 如果物体在运动并且你想检测你可以使用光流结合最大轮廓来检测物体。
  3. 尝试在没有模糊功能的情况下进行处理,然后检测最大的 contourArea。
  4. 要绘制点,试试这个

    for(int i = 1;i<(int)largest_contours[0].size();i++)
         line(image,largest_contours[0][i-1],largest_contours[0][i],cv::Scalar(0,0,255),2,8,0);
    

关于c++ - 使用 C++ FindContours 在视频图像中查找轮廓的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14706163/

相关文章:

c++ - 如何通过程序扫描系统内存?

c++ - 类切片导致的未处理异常

Java和OpenCV颜色检测

c# - OpenCV 直方图掩码

java - 谷歌眼镜上的计算密集型任务

c++ - Qt - 将空指针(原始数据)转换为 QImage 并将其显示在标签上

c++ - 以字符数组为参数的模板元编程

python - 如何使nii图像的深度相等?

javascript - 我可以在不使用图像元素的情况下将图像直接加载到 Canvas 上吗

python - 如何使用 OpenCV 找到最大的空矩形?