2016-03-02 2 views
0

Я пытаюсь сделать систему распознавания рук, но когда я использовал оттенки серого для cvtColor, я получаю подтверждение отладки, но когда я использую HSV, код работает нормально. Можете ли вы это решить? Я новичок в opencv.Ошибка отладки при использовании grayscale

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


using namespace std; 
using namespace cv; 

int thresh = 100; 


int findBiggestContour(vector<vector<Point> > contours){ 
    int indexOfBiggestContour = -1; 
    int sizeOfBiggestContour = 0; 
    for (int i = 0; i < contours.size(); i++){ 
     if (contours[i].size() > sizeOfBiggestContour){ 
      sizeOfBiggestContour = contours[i].size(); 
      indexOfBiggestContour = i; 
     } 
    } 
    return indexOfBiggestContour; 
} 

void shifcontour(vector<Point>& contour, int x, int y) 
{ 
    for (size_t i = 0; i<contour.size(); i++) 
    { 
     contour[i].x += x; 
     contour[i].y += y; 
    } 
} 
int main() 
{ 
    cout << "beginning"; 

    VideoCapture cap("pathaka.MP4"); 

    if (!cap.isOpened()) // check if we succeeded 
     return -1; 

Ptr<BackgroundSubtractor> pMOG2 = createBackgroundSubtractorMOG2(); 
    for (;;) 
    { 
     Mat original, img; 
     cap >> img; 
     imshow("Source", img); 

     Mat hsv; 
     cvtColor(img, hsv, CV_BGR2GRAY); 

     Mat bw; 
     inRange(hsv, Scalar(0, 30, 80), Scalar(20, 150, 255), bw); 
     GaussianBlur(bw, bw, Size(7, 7), 1.5, 1.5); 
     Canny(bw, bw, 0, 30, 3); 


     vector<vector<Point> > contours; 
     vector<vector<Point> > convex_hull; 
     vector<Vec4i> hierarchy; 


     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)); 

     dilate(bw, bw, element); 

     findContours(bw, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); 

     int s = findBiggestContour(contours); 

     Mat drawing = Mat::zeros(img.size(), CV_8UC1); 

     dilate(drawing, drawing, getStructuringElement(MORPH_ELLIPSE, Size(5, 5))); 
     dilate(drawing, drawing, getStructuringElement(MORPH_ELLIPSE, Size(5, 5))); 

     std::vector<cv::Point> cnt; 
     cnt = contours[s]; 

     Moments M; 
     M = cv::moments(cnt); 

     cv::Point result; 
     result = cv::Point(M.m10/M.m00, M.m01/M.m00); 

     Point center(drawing.cols/2, drawing.rows/2); 

     cv::circle(drawing, center, 3, Scalar(255, 255, 255), -1, 8, 0); 


     int x; 
     if (result.x > center.x) 
     { 
      x = result.x - center.x; 
      x = -x; 
     } 
     else 
     { 
      x = result.x - center.x; 
     } 

     int y; 

     if (result.y < center.y) 
     { 
      y = center.y - result.y; 
     } 
     else 
     { 
      y = center.y - result.y; 
     } 

     cout << "x:" << x << endl; 
     cout << "y: " << y << endl; 


     shifcontour(contours[s], x, y); 

     drawContours(drawing, contours, s, Scalar(255), -1, 8, hierarchy, 0, Point()); 

     imshow("Hsv", drawing); 
     if (waitKey(30) >= 0) break; 
    } 

    return 0; 
} 
+0

Где происходит утверждение? Получаете ли вы конкретное сообщение? –

+0

Ошибка отладки! Программа: C: \ Windows \ system32 \ MSVCP120D.dll Файл: c: \ program files \ microsoft visual studio12.0 \ vc \ include \ vector Строка: 1201 Выражение: векторный индекс вне диапазона – aelita0209

ответ

1

Я думаю, что проблема:

findContours(bw, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); 

contours может теперь иметь что-то внутри, но это может быть пустым, верно? Затем вы делаете это:

int s = findBiggestContour(contours); 

Если contours.size() == 0, то s == -1, правильно?

Но после этого, вы делаете это:

std::vector<cv::Point> cnt; 
cnt = contours[s]; 

Если contours пуст, contours[-1] бросает vector subscript out of range.

Вы должны проверить if (s != -1) перед использованием contours[s], ок?

Может быть, вы должны обрабатывать контуры только если есть, например:

findContours(bw, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); 

if (contours.size() > 0) { 
    int s = findBiggestContour(contours); 

    Mat drawing = Mat::zeros(img.size(), CV_8UC1); 
    // these dilates are useless, because drawing is an empty image! 
    dilate(drawing, drawing, getStructuringElement(MORPH_ELLIPSE, Size(5, 5))); 
    dilate(drawing, drawing, getStructuringElement(MORPH_ELLIPSE, Size(5, 5))); 

    std::vector<cv::Point> cnt = contours[s]; 

    Moments M = cv::moments(cnt); 
    Point result = cv::Point(M.m10/M.m00, M.m01/M.m00); 
    Point center(drawing.cols/2, drawing.rows/2); 
    circle(drawing, center, 3, Scalar(255, 255, 255), -1, 8, 0); 

    int x; 
    if (result.x > center.x) { 
     x = result.x - center.x; 
     x = -x; 
    } else { 
     x = result.x - center.x; 
    } 

    // is this correct? y has the same value in both cases... 
    int y; 
    if (result.y < center.y) y = center.y - result.y; 
    else y = center.y - result.y; 

    cout << "x:" << x << endl; 
    cout << "y: " << y << endl; 

    shifcontour(contours[s], x, y); 
    drawContours(drawing, contours, s, Scalar(255), -1, 8, hierarchy, 0, Point()); 
    imshow("Hsv", drawing); 
} 
Смежные вопросы