我在使用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);
答案 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
时交换j
和Point
,或者不要使用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访问像素,我的问题得到了解决。