Ask Your Question
1

ROI for trapezoid

asked 2014-10-07 22:22:10 -0600

zms gravatar image

Hello everyone, is there OPENCV function that can set the ROI shape other than rectangle? ie trapezoid shape?

When I did some research in the internet, looks like the binary mask is one option to mask it as theory but no example.

Other than that, is polygonal... If anyone have idea on this, I do appreciate it if can be shared.

Zamani

edit retag flag offensive close merge delete

Comments

1

Yes, a binary mask with the shape of the trapezoid (or quadrilateral) filled in is the way to go. Please see this answer: http://answers.opencv.org/question/43430/how-to-replace-information-in-a-mat-based-on-a/?answer=43452#post-id-43452

rwong gravatar imagerwong ( 2014-10-07 22:39:33 -0600 )edit

Do I have to create the mask by myself on a new Mat image using a black and white for eg. the trapezium is white and the background is black? with the same size of the image I want to get the ROI?

If I use this type of ROI, can it be also processed like when I had used the rect ROI? I ask this because when I'm using the rect ROI, I don't see any black background. Appreciate on the response.

Zamani

zms gravatar imagezms ( 2014-10-08 03:00:08 -0600 )edit
1

Yes, with filPoly or fillConvexPoly

thdrksdfthmn gravatar imagethdrksdfthmn ( 2014-10-08 04:04:41 -0600 )edit
1

Yes you will have to make the mask yourself. Most of the times the mask is made white and the background black. It depens on where you want to apply that ROI mask if it is possible or not, some functions simply don't allow using a mask, but most of the times pre- of postprocessing can do the trick.

StevenPuttemans gravatar imageStevenPuttemans ( 2014-10-08 04:05:26 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
3

answered 2014-10-08 14:39:55 -0600

rwong gravatar image

Yes, a binary mask with the shape of the trapezoid (or quadrilateral) filled in is the way to go. Please refer to this question for details.

Firstly, create a single-channel matrix filled with black. Then, use fillPoly or fillConvexPoly to paint the trapezoid area white. Finally, use this matrix as the mask for OpenCV methods that support mask matrix, or use bitwise operations to preprocess or post-process images for OpenCV methods that do not support mask matrix. The details are described in the link mentioned above.


The reason why irregular masking cannot be handled the same way as rectangular ROI is due to the low-level algorithm coding.

Please read: Array slicing (computer programming) - article on Wikipedia

When a rectangular sub-region of a matrix is processed by an algorithm, it can be implemented a two-level for-loop over its rows and columns. The choice of the rectangular sub-region affects the lower and upper limits of the two level for-loops. Aside from that, the code needed for processing the rectangular region can be surprisingly similar to the code needed for processing the whole matrix.

For irregularly-shaped regions, it would not be sufficient just to control the lower and upper limits of the two-level for-loop. Instead, each pixel has to be checked for its region membership - whether it is inside the region or outside. An algorithm that performs this check is equivalent to an algorithm that relies on a user-provided mask matrix to define the irregularly-shaped region.


If you would like to rectify a trapezoid-shaped object, you can use OpenCV geometrical transforms so that the trapezoid-shaped object will be flattened out to a rectangle.


Thanks to StevenPuttemans, thdrksdfthmn and kbarni for providing the details for this answer.

edit flag offensive delete link more

Comments

OK guys, thanks for the input but I stucked currently at this process. Now I have the mask by using the fillpoly and the src image. And how to to complete the mask? I look at the example to do this operation below but failed. I'm not sure the last stage now.. APpreciate if anyone can point me to the correct path. platemask = src & maskimage; Full Code

zms gravatar imagezms ( 2014-10-10 02:20:31 -0600 )edit
int main(int argc, char** argv)
{
Mat src=imread("c:\\a.jpg",1); // fill it however you want to
Mat maskimage = Mat::zeros( 576, 1024, CV_8UC1 );

MyPolygon(maskimage);
imshow("mask image",maskimage);

platemask = src & maskimage;
imshow("mask",platemask);

waitKey(0);

return 0;

zms gravatar imagezms ( 2014-10-10 02:25:44 -0600 )edit

not sure the above code cannot show platemask = src & maskimage and not platemask = src& maskimage which is not correct.

zms gravatar imagezms ( 2014-10-10 02:40:48 -0600 )edit

Hi there, keep debugging for few more hours but had not yet success. I understand the failure message is about not having the same type of image. My src is a jpeg while the mask is a binary image. it does not match.. Please help to give some ideas why I cannot move. Mat src=imread("c:\a.jpg",1); // fill it however you want imshow("src",src);

Mat rook_image = Mat::zeros( 576, 1024, CV_8UC1 ); MyPolygon( rook_image ); imshow("image",rook_image);

Mat res;
bitwise_and(src,rook_image,res);     imshow("AND",res);

Failure message: OpenCV Error: Sizes of input arguments do not match (The operation is neither 'a rray op array' (where arrays have the same size and type), nor 'array op scalar' , nor 'scalar op array') in cv::binary_op, file ......\sources\modules\core\sr c\arithm.cpp

zms gravatar imagezms ( 2014-10-10 07:27:43 -0600 )edit

OK finally it work... But I want to ask because in the early of the response I was recommended to use CV_8UC1 for the mask image. Due to the image I have is 3 channels image, so I had change to this.

int main(int argc, char** argv) {

//
Mat src=imread("c:\a.jpg",1); // fill it however you want imshow("src",src);

Mat rook_image = Mat::zeros( 576, 1024, CV_8UC3 ); MyPolygon( rook_image ); // please refer to tutorial drawing using fill poly by OpenCV imshow("image",rook_image);

Mat res;
bitwise_and(src,rook_image,res);     imshow("AND",res);

Question - what is the impact of using the 3 channels instead of 1?

Can I consider this as the ROI like the rect() function to do the processing? Is it going to optimize it? I asked because the MAT still have the full size 1057X576

zms gravatar imagezms ( 2014-10-10 10:35:47 -0600 )edit

Apologies for my earlier incorrect recommendation. If the API method accepts a "mask matrix", that matrix should be single-channel. This treatment is also known as a "Predicate" in Computer Science. However, if you are doing the masking with "bitwise_and", then the second argument to that element-wise bitwise operation need to have the same type and same number of channels as the first argument. The reason is that "bitwise_and" does not treat any of the two argument specially.

rwong gravatar imagerwong ( 2014-10-16 16:29:01 -0600 )edit

Question Tools

Stats

Asked: 2014-10-07 22:22:10 -0600

Seen: 6,596 times

Last updated: Oct 08 '14