如何解决OpenCV中的“访问冲突读取位置”错误?

时间:2014-07-10 06:33:09

标签: c++ opencv

我在使用OpenCV进行抓取时遇到以下运行时错误。

"Access violation reading location"

我要做的是从面部探测器和背景提取器中获取种子以进行抓取。
来自我的面部检测器的种子存储在PrFg_seed_FaceExtended(面部检测矩形延伸到最后一行),Fg_seed_inside_face(检测到面部内的较小矩形) countoursFrame中所有红色的像素都是我想要添加到种子的附加像素。任何想法我怎么能这样做?

有趣的是,在视频中处理了三个帧后,会出现此运行时错误。

如果我排除for循环,我试图将contoursFrame中的红色像素标记为GC_PR_FGD,则代码似乎工作正常。

contoursFrame只是框架的克隆。我使用contoursFrame上的drawContours函数绘制轮廓。

代码段:

cv::Mat1b markers(frame.rows,frame.cols);
        cv::Mat1b fg_seed_inside_face = markers(rectangle_inner);
        cv::Mat1b Prfg_seed_FaceExtended = markers(rectangle_outer);

        markers.setTo(cv::GC_PR_BGD);
        Prfg_seed_FaceExtended.setTo(cv::GC_PR_FGD);
        fg_seed_inside_face.setTo(cv::GC_FGD);





        for(i=0;i<frame.rows;i++){
            for(j=0;j<frame.cols;j++){
                if ((contoursFrame.at<Vec3b>(Point(i,j))[0]==0) && (contoursFrame.at<Vec3b>(Point(i,j))[1]==0) && (contoursFrame.at<Vec3b>(Point(i,j))[2]==255)){
                    //cout << "\nFound a red pixel";
                    markers.at<uchar>(i,j) = cv::GC_PR_FGD;
                }
            }
        }

        waitKey(100);


        cv::Mat bgd, fgd;
        int iterations = 1;
        cv::grabCut(frame, markers, cv::Rect(), bgd, fgd, iterations, cv::GC_INIT_WITH_MASK);
        cout << "Grabcut Worked!";
        cv::Mat1b mask_fgpf = ( markers == cv::GC_FGD) | ( markers == cv::GC_PR_FGD);

2 个答案:

答案 0 :(得分:2)

您正在使用Point(int _x, int _y),但根据您的for循环提供(row,col)。它会崩溃,除非你有一个方框,但是列数比行数多,你要从框架的数据缓冲区中读得更多,并且可能会更快崩溃。这是因为cv::Mat将数据存储在row-major order中(一行接一行)。

请注意docs for at声明了at(int i, int j)at(Point pt)用法,并将pt指定为:

pt – Element position specified as Point(j,i)

这意味着您需要在调用i时交换jPoint,或者不要使用at

答案 1 :(得分:0)

我不太清楚@ chappjc的评论是什么意思,但我认为他确实指出了问题的根源。

通过进行以下更改解决了这个问题:

if (
    (countoursFrame.at<Vec3b>(i,j).val[0]==0) && 
    (countoursFrame.at<Vec3b>(i,j).val[1]==0) && 
    (countoursFrame.at<Vec3b>(i,j).val[2]==255)
)

基本上,我认为Point(i,j)将访问countoursFrame中的i,j像素。通过使用val访问像素,我的问题得到了解决。