ROI is the abbreviation of Region Of Interest, which literally means the area of interest, or the "target area" that needs to be operated.
If you want to operate on the ROI area, you must first select and obtain this area.
The easiest way is to use Numpy's array index slice to obtain a rectangular ROI (of course, other shapes of ROI may be more suitable for some objects in specific situations, but obviously it cannot be obtained by such a simple method, it must beIt can only be obtained after an algorithm with a certain complexity).
Assuming that an image has a width and height of [400, 400] and the number of channels is 3, then if you want to select an object with a width and height of [40, 40] in the middle, you can use the following slice index
img[180:220, 180:220, :]
Reference: OpenCV: Miscellaneous ImageTransformations-floodfill()
Typical application of flood fill: fill adjacent areas with similar values to the target pixel; similar to the function achieved by the magic wand tool in Adobe Photoshop.
The API to implement floodfill is floodfill(), the syntax is as follows
cv.floodFill(image, mask, seedPoint, newVal[, loDiff[, upDiff[, flags]]]) ->retval, image, mask, rect
Talk about macro parameters
We can also know from the official API documentation of floodfill() that flags have low, medium and high eight bits; and the high eight bits are defined by macro parameters.
When we were learning the C language, we talked about using the define command to define macro objects, such as defining the commonly used constant 3.1415926...the constant π as PI, so that we don't need to keep such a long string of numbers all the time.After typing it out, or for students with poor memory, there is no need to memorize the numbers after the decimal point of π.
In order to make programming easier for humans, without having to remember those numbers that are not intuitive, the developers of OpenCV predefine several macro parameters for the values corresponding to several options in the upper eight bits. Our programThe operator simply passes the macro parameter string into the API.
Finally, let's talk about an error. Everyone executes the following code; you will find that the mask has not changed, and the image has also changed.
import cv2 as cvimport numpy as npdef fill_binary():image = np.zeros([400, 400, 3], np.uint8)image[100:300, 100:300, :] = 255cv.imshow("fill_binary", image)mask = np.ones([402, 402, 1], np.uint8)mask[101:301, 101:301] = 0print(np.sum(mask))cv.floodFill(image, mask, (200, 200), (0, 0, 255), 4 | (127 << 8) | cv.FLOODFILL_MASK_ONLY)cv.imshow("filled binary", image)print(np.sum(mask))print(np.unique(mask))cv.imshow("mask", mask)fill_binary()cv.waitKey(0)cv.destroyAllWindows()
This is because there are two loDiff and upDiff parameters in front of the flags parameter; if you do not pass values to these two parameters, and do not pass a value to the parameter flags in the form of a keyword parameter, the function will mistake the flagsThe value passed into loDiff is obviously wrong.
After modifying to the correct version below.
import cv2 as cvimport numpy as npdef fill_binary():image = np.zeros([400, 400, 3], np.uint8)image[100:300, 100:300, :] = 255cv.imshow("fill_binary", image)mask = np.ones([402, 402, 1], np.uint8)mask[101:301, 101:301] = 0print(np.sum(mask))cv.floodFill(image, mask, (200, 200), (0, 0, 255), flags=4 | (127 << 8) | cv.FLOODFILL_MASK_ONLY)cv.imshow("filled binary", image)print(np.sum(mask))print(np.unique(mask))cv.imshow("mask", mask)fill_binary()cv.waitKey(0)cv.destroyAllWindows()
That's right!