使用灰度时调试断言失败

Debug assertion fail when using grayscale

本文关键字:断言 失败 调试 灰度      更新时间:2023-10-16

我正在尝试制作一个手部识别系统,但是当我对cvtColor使用灰度时,我得到调试断言失败,但是当我使用HSV时,代码工作正常。你能解决这个问题吗?我是opencv的新手。

#include "stdafx.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/objdetect.hpp"
#include < opencv2opencv.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;
}

我认为问题是:

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

你应该在使用contours[s]之前检查if (s != -1),好吗?

也许您应该仅在存在轮廓时才处理轮廓,如下所示:

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