If you want to fill out a part of an image or video in black and crop it, create a mask for the image and overlay it.
The original image Masked image
Use Numpy to create a mask where the area you want to blacken is 0 and the area you want to crop is 1. When I thought that I could mask by multiplying each element of the matrix, the output was different from what I expected.
h_img, w_img = img.shape[:2]
mask = np.zeros((h_img, w_img, 3))
radius = int(h_img / 2)
center = radius
cv2.circle(mask, (center, center), radius, (1, 1, 1), thickness=-1, shift=0)
masked_img = img * mask
Mask made with Numpy
Masked image (masked_img)
When defining a matrix in Numpy, if you don't specify dtype, it defaults to float64. On the other hand, the image read by imread of opencv is read by CV_8U, CV_16F, CV_32F (usually CV_8U) depending on its brightness. With CV_8U, the Numpy data type supports np.uint8. In other words, in the failed example, the image of CV_8U is masked with float64 type.
When defining a matrix in Numpy, specify the type to np.uint8. did it.
mask = np.zeros((h_img, w_img, 3), dtype=np.uint8) #Specify type as uint8
Masked image
When I try to display the mask as an image, it is pitch black.
It's a rudimentary mistake of data type mismatch, but it took me a while to notice, probably because I've been using only python lately and have less chance to be aware of the type. In the first place, instead of defining it in np.zeros, I should have used np.zeros_like to define the matrix including the image type.
Recommended Posts