Im trying to create a rectangle ROI over webcam video. But this code is crashing
#include "opencv2/opencv.hpp"
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
using namespace cv;
int main(){
VideoCapture cap(0);
if(!cap.isOpened()){
cout << "Error opening video stream or file" << endl;
return -1;
}
Rect Roi(1,1,100,200);
while(1){
Mat frame;
cap >> frame;
frame.copyTo(frame(Roi));
// If the frame is empty, break immediately
if (frame.empty())
break;
// Display the resulting frame
imshow( "Frame", frame );
moveWindow("Frame",500,100);
// Press ESC on keyboard to exit
char c=(char)waitKey(25);
if(c==27)
break;
}
cap.release();
destroyAllWindows();
return 0;
}
// g++ cam_roi.cpp pkg-config --cflags --libs opencv4
; ./a.out
ERROR ==> [ WARN:0] global ../modules/videoio/src/cap_gstreamer.cpp (961) open OpenCV | GStreamer warning: Cannot query video position: status=0, value=-1, duration=-1 terminate called after throwing an instance of 'cv::Exception' what(): OpenCV(4.5.1) ../modules/core/src/matrix_wrap.cpp:1188: error: (-215:Assertion failed) !fixedSize() || ((Mat*)obj)->size.operator()() == Size(_cols, _rows) in function 'create'
Aborted
the core issue is
(-215:Assertion failed) !fixedSize() || ((Mat*)obj)->size.operator()() == Size(_cols, _rows) in function 'create'
(the gstreamer line is just a warning)
this error comes from that line (it's not obvious but copyto
involves a Mat::create
call):
frame.copyTo(frame(Roi));
copyTo
gets the destination Mat as the argument. it can resize the destination in some circumstances.
frame(Roi)
is a "view" into frame
, and views can't be resized, i.e. they are "fixed size".
you seem to want to take that subregion and put it back into frame.
if that line of code worked, it would do the opposite, i.e. put the data from the whole frame
into a subregion of itself...
simply do this:
frame = frame(Roi);
this will keep the view. you can use it as usual. the whole data of frame
will live as long as the view.
the view's data will not be contiguous, if that's a concern.
to "fix" that, you can create a copy that'll be contiguous:
frame = frame(Roi).clone();