在opencv中找到最大轮廓的手

时间:2016-03-02 07:34:07

标签: c++ opencv

我正在研究手部识别系统,我是初学者。我试图通过找到最大的轮廓(即手)来检测手,但它在整个框架上而不是在手上绘制一个矩形。我该如何解决?

#include "stdafx.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv\cv.h"
#include <iostream>
#include <stdlib.h>
#include <stdio.h>

using namespace cv;
using namespace std;




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

Mat edges;
namedWindow("edges", 1);

int largest_area = 0;
int largest_contour_index = 0;
Rect bounding_rect;

for (;;)
{
    Mat frame;
    cap >> frame; // get a new frame from video
    Mat dst(frame.rows, frame.cols, CV_8UC1, Scalar::all(0));
    cvtColor(frame, edges, CV_BGR2GRAY);
    threshold(edges, edges, 22, 44, THRESH_BINARY);
    GaussianBlur(edges, edges, Size(7, 7), 1.5, 1.5);
//  Canny(edges, edges, thresh, thresh*2, 3);
    int erosion_type = MORPH_ELLIPSE;
    int erosion_size = 0;
    Mat element = getStructuringElement(erosion_type, Size(2 * erosion_size + 1, 2 * erosion_size + 1), Point(erosion_size, erosion_size));
    erode(edges, edges, element);
    dilate(edges, edges, element);

    vector<vector<Point>>contours; //Vector for storing contour
    vector<Vec4i> hierarchy;

    findContours(edges, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE); // Find the contours in the image

    for (int i = 0; i< contours.size(); i++) // iterate through each contour. 
    {
        double a = contourArea(contours[i], false);  //  Find the area of contour
        if (a>largest_area){
            largest_area = a;
            largest_contour_index = i;                //Store the index of largest contour
            bounding_rect = boundingRect(contours[i]); // Find the bounding rectangle for biggest contour
        }

    }
    Scalar color(255, 255, 255);
    drawContours(dst, contours, largest_contour_index, color, CV_FILLED, 8, hierarchy); // Draw the largest contour using previously stored index.
    rectangle(frame, bounding_rect, Scalar(0, 255, 0), 1, 8, 0);

    imshow("src", frame);
    imshow("largest contour", dst);
    if (waitKey(30) >= 0) break;

}

// the camera will be deinitialized automatically in VideoCapture destructor




return 0;
}

1 个答案:

答案 0 :(得分:1)

首先, cv :: findContour()不仅可以填充输出轮廓数组,还可以更改输入Mat图像。 因此,如果您使用全局源Mat图像实例的findContour(),请尝试使用findContour(src.clone(),dat等)而不是findContour(src,dat等)。

其次, 变量&quot; largest_contour_index&#39;在(;;)循环外部初始化并仅在出现较大轮廓时设置为特定值,因此可能导致数组超出界限错误。

所以在你的代码中,

CONVERSION

Base 11 to Decimal
Base 11: 1234AB 


编辑:
如果您的图像背景颜色比手颜色更亮,带CV_RETR_CCOMP的cv :: findContour()将首先检测整个帧。
请尝试使用CV_RETR_TREE。

sudo rpm -Uvh --oldpackage python-devel-2.7.5-18.el7_1.1.x86_64.rpm  python-libs-2.7.5-18.el7_1.1.x86_64.rpm  python-2.7.5-18.el7_1.1.x86_64.rpm

如果发生同样的事情,有3种选择:

1.反转垫子的颜色。
请注意,这将消耗少量时间。

largest_contour_index = -1;
largest_area = 0;

findContours(edges.clone(), contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE); // Find the contours in the image

for (int i = 0; i< contours.size(); i++) // iterate through each contour. 
{
    double a = contourArea(contours[i], false);  //  Find the area of contour
    if (a>largest_area){
        largest_area = a;
        largest_contour_index = i;                //Store the index of largest contour
        bounding_rect = boundingRect(contours[i]); // Find the bounding rectangle for biggest contour
    }

}

if(largest_contour_index >= 0)
{
    Scalar color(255, 255, 255);
    drawContours(dst, contours, largest_contour_index, color, CV_FILLED, 8, hierarchy); // Draw the largest contour using previously stored index.
    rectangle(frame, bounding_rect, Scalar(0, 255, 0), 1, 8, 0);
}


2.选择第二大的。

findContours(edges.clone(), contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); // Find the contours in the image


3.如果轮廓的大小几乎等于Mat的大小,则忽略。

cv::cvtColor(edges, edges, CV_BRG2GRAY);   // if your org image is not grayscale
edges = 255-edges;

3。使用层次结构
我建议你使用层次结构,虽然起初使用起来有些复杂。
read this page for using hierarchy