Reputation: 115
My goal is to pad my segmented image with zeros along the border as I needed to close it (for filling in small holes in my foreground). Here tmp
is an CV_8UC3 segmented image Mat
obtained from my image frame
, in which all my background pixels have been blacked out. I have manually created a binary mask from tmp and stored it in Mat bM
, which is the same size and type as my image Mat frame
.
Mat bM = Mat::zeros(frame.rows, frame.cols, CV_8UC1);
for(i=0;i<frame.rows;i++)
{
for(j=0;j<frame.cols;j++)
{
if(tmp.at<Vec3b>(i,j)[0] != 0 && tmp.at<Vec3b>(i,j)[1] != 0 && tmp.at<Vec3b>(i,j)[0] != 0)
bM.at<uchar>(i,j) = 255;
}
}
Mat padded;
int padding = 6;
padded.create(bM.rows + 2*padding, bM.cols + 2*padding, bM.type());
padded.setTo(Scalar::all(0));
bM.copyTo(padded(Rect(padding, padding, bM.rows, bM.cols)));
My execution breaks at the last line in Visual Studio giving the following error:
Assertion failed <0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols && 0<=roi.height && roi.y+roi.height <=m.rows>
While I understand what that means, I cant figure out why it would throw this error as my source image is within bounds of my target image. I've stepped through my code and am sure it breaks at that specific line.
From what I've read, the cv::Rect constructor can be given offsets the way I've passed the offsets padding
and padding
, and these offsets are taken from the top left corner of the image. Can the copyTo function be used this way? Or is my error elsewhere?
Upvotes: 1
Views: 426
Reputation: 1025
The CV::Rect constructor is different from the CV::Mat constructor.
Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
The cv::Rect parameters are offset in x, offset in y and then width first and height at last.
So when you do this:
bM.copyTo(padded(Rect(padding, padding, bM.rows, bM.cols)));
You create a cv::Rect with width bM.rows and heigth bM.cols. Which is the oposite of what you need. Change it to:
bM.copyTo(padded(Rect(padding, padding, bM.cols, bM.rows)));
Upvotes: 1