user4028648
user4028648

Reputation:

Python OpenCV: Why does fillPoly() only draw grey polygons, regardless of its color argument?

I am trying to write a white mask on a black, two-dimensional NumPy array — an image with one channel — in OpenCV using Python:

mask = np.zeros(shape=(100, 100), dtype=np.int8)
cv2.fillPoly(mask, np.array([[[0,0], [89, 0], [99,50], [33,96], [0,47]]], dtype=np.int32), color=255)
print(mask)

However, the polygon has a grey color when I print the mask:

[[127 127 127 ...   0   0   0]
 [127 127 127 ...   0   0   0]
 [127 127 127 ...   0   0   0]
 ...
 [  0   0   0 ...   0   0   0]
 [  0   0   0 ...   0   0   0]
 [  0   0   0 ...   0   0   0]]

I tried a 3D NumPy array with color=(255,255,255), I tried different colours, all to no avail. Why is it ignoring the color argument?

Upvotes: 2

Views: 4834

Answers (3)

joydeba
joydeba

Reputation: 1245

For me the problem was not initializing the mask with depth.

mask = np.zeros(shape = (MASK_WIDTH, MASK_HEIGHT), dtype=np.uint8)

Solved with this code

mask = np.zeros(shape = (MASK_WIDTH, MASK_HEIGHT, 3), dtype=np.uint8)
rcolor = list(np.random.random(size=3) * 256)
cv2.fillPoly(mask, [arr], color=rcolor) 
cv2.imwrite(os.path.join(mask_folder, itr + ".jpg") , cv2.cvtColor(mask, cv2.COLOR_RGB2BGR))

Upvotes: 2

Mibez
Mibez

Reputation: 21

The problem lies in the datatype selection when initializing the numpy array. In your example code you are using np.int8 , which has a range from -128 ... 127.. Instead of np.int8 you should consider using np.uint8, which has a range of 0 ... 255, whixh you are looking for.

mask = np.zeros(shape=(100, 100), dtype=np.int8)

should be

mask = np.zeros(shape=(100, 100), dtype=np.uint8)

[[255 255 255 ... 0 0 0] [255 255 255 ... 0 0 0] [255 255 255 ... 0 0 0] ... [ 0 0 0 ... 0 0 0] [ 0 0 0 ... 0 0 0] [ 0 0 0 ... 0 0 0]]

Upvotes: 2

HansHirse
HansHirse

Reputation: 18925

The problem comes from the initialization of your mask:

mask = np.zeros(shape=(100, 100), dtype=np.int8)

The value range of the int8 data type is -128 ... 127, thus any value above 127 will be "truncated" to 127.

Try your code with color=100, you'll get the expected output:

[[100 100 100 ...   0   0   0]
 [100 100 100 ...   0   0   0]
 [100 100 100 ...   0   0   0]
 ...
 [  0   0   0 ...   0   0   0]
 [  0   0   0 ...   0   0   0]
 [  0   0   0 ...   0   0   0]]

I guess, you wanted to use uint8 instead of int8, so maybe it's just a simple typo!?

Changing your code accordingly to

mask = np.zeros(shape=(100, 100), dtype=np.uint8)

then gives the expected result, also for color=255:

[[255 255 255 ...   0   0   0]
 [255 255 255 ...   0   0   0]
 [255 255 255 ...   0   0   0]
 ...
 [  0   0   0 ...   0   0   0]
 [  0   0   0 ...   0   0   0]
 [  0   0   0 ...   0   0   0]]

Upvotes: 4

Related Questions