程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

【 OpenCV - Python - course (jia) 】 OpenCV3.3 course notes: ROI and flood fill (slice indices, watershed), the magic wand tool in OpenCV

編輯:Python

I. What is ROI?

ROI is the abbreviation of Region Of Interest, which literally means the area of ​​interest, or the "target area" that needs to be operated.

Second, how to obtain ROI?

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, :]

Three, flood fill - floodfill()

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

  • image is the original image, unless the upper eight bits of flags are set to cv.FLOODFILL_MASK_ONLY, the function will make changes to the image.image can be a single-channel grayscale image or a multi-channel color image.
  • mask is a mask, which must be a single-channel unsigned 8-bit integer array, and its width and height are 2 larger than those of the original image; the zero-value area in the mask is used to limit the area where the image changes, whileThe non-zero value area will block the flood filling; the mask is both an input and an output. Compared with the original, the flooded area is filled with 1 or the middle 8-bit value in the flags (explained in the flags later).
  • seedPoint is the flooding base point, that is, the "flooding" starts to expand outwards until it encounters the mask boundary or exceeds the loDiff and upDiff boundaries; when flags is not specified as cv.FLOODFILL_FIXED_RANGE, except for 4 or 8 near the base pointEach pixel is judged according to it, and other pixels are judged according to the point on the boundary point neighborhood range that is already in the flooded area; when flags is specified as cv.FLOODFILL_FIXED_RANGE, all pixels are based on this point.judge.
  • newVal is the flood fill value, if the original image is a single-channel image, newVal is a single value, and if the original image is a three-channel image, newVal should be a tuple of length 3.
  • loDiff and upDiff are the difference between the lower and upper boundaries respectively, which are consistent with the length of newVal. Only when the pixel is greater than the judgment base point minus the loDiff value and less than the plus upDiff value, it will be classified into the flooding area.
  • flags has a total of 3 bytes, the lower eight bits represent the neighborhood range, the default is 4, and it can also be set to 8; the middle eight bits represent the value to be filled in the mask, for example (255 << 8) means that 255 leftThe result obtained by shifting eight bits; if the upper eight bits are not set, it means that the image image will be changed, and it is the way to judge the flooding area with float_range. If it is set to cv2.FLOODFILL_FIXED_RANGE, it means that it is only based on the pixel difference with the flooding base point.The value determines whether it belongs to the flooding area. If it is set to cv2.FLOODFILL_MASK_ONLY, it means that the image image is not changed, but only the mask is changed; The only thing I have doubts is whether cv2.FLOODFILL_FIXED_RANGE can match theDoes cv2.FLOODFILL_MASK_ONLY exist together??It's logically perfectly fine.
  • rect is the coordinates, width and height of the smallest rectangular boundary of the finally obtained flooding area.

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!


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved