0

I'm gonna to crop an image by using row and column detection. When it detect the black pixel, then it will know the column or row need to crop but the python show me;

if img[y,x] == [0]: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Here is the image

enter image description here

Can anyone please tell me what am i doing wrong?

import cv2
import numpy as np
img = cv2.imread('C:/Users/user/Desktop/FYP 2019/Sign Language 1/red1.png')
gray = cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(5,5),0)
ret,thresh = cv2.threshold(blur,125,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
#get the images dimensions 
h = img.shape[0]
w = img.shape[1]
lower_min_point = -1
upper_min_point = -1
left_point = -1
right_point = -1
for y in range(0, h):
    for x in range(0,w):
        if img[y,x] == [0]:
            lower_min_point = y             
            break
    if lower_min_point != -1:
        break
print (lower_min_point)
for y in range(h,0):
    for x in range(0,w):
        if img[y,x] == [0]:
            upper_min_point = y
            break
    if upper_min_point != -1:
        break
print(upper_min_point)

for x in range(0,w):
    for y in range(0,h):
        if img[y,x] == [0]:
            left_point = x
            break
    if left_point != -1:

            break
    print(left_point)       
    for x in range(w,0):
        for y in range(0,h):
            if img[y,x] == [0]:
                right_point = x
                break
        if right_point != -1:
            break
    print(right_point)
    crop = img[lower_min_point:upper_min_point, left_point:right_point]
    cv2.imshow("img",crop)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
Giorgio
  • 1,973
  • 4
  • 36
  • 51
pohyu lim
  • 1
  • 1
  • 1

2 Answers2

0

img is a 3-d array. Therefore img[x,y] will be a vector and your comparison will actually test the condition for each element in the vector. So it will return array([True, True, True]) if all image channels are actually 0. The error message you get already gives you the solution: call .all() on the resulting vector (this will check whether the condition holds true for all elements in the array).

(img[x,y] == [0]).all() will give you the desired behaviour.

ahammond
  • 31
  • 6
  • thanks it can works but why it cannot read the black pixels value after i threshold the point become black and background was white? my lower_min_point and left_point get 0 value, upper_min_point and right_point get -1. i print (img[y,x]) only get [ 0 0 0]. Any recommend? – pohyu lim Apr 29 '19 at 14:52
  • Why your code is not cropping your image seems like a different question than why you get the ValueError. Luckily it looks like somebody already answered that question here: https://stackoverflow.com/a/13539194/8130122 – ahammond Apr 30 '19 at 13:46
0

If you want to check if any python iterable contains all True values, you can use all.

zero_channels = [channel == 0 for channel in img[y, x]]  # python list of bools
if all(zero_channels):
  ...

As it turns out, the same thing can be done using numpy array equality (cv2 images/slices are numpy arrays for this purpose) and np.logical_all:

zero_channels = img[y, x] == 0  # element-wise equality, returns np.array of bools
if np.logical_all(zero_channels):
  ...

Once you're comfortable with these ideas, you can clean things up by putting them in the same line, e.g.

if np.logical_all(img[y, x] == 0):
   ...
DomJack
  • 4,098
  • 1
  • 17
  • 32