3

I'm trying to change the color of a certain image to a new color. But when running the code below. The following error appears:

Traceback (most recent call last) File "/home/vagner/PycharmProjects/TestesDeBorda/DesenharRetangulo.py", line 16, in

if (image[i, j] > minCorAgua - image[i, j] < maxCorAgua).all():

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

import cv2    

minCorAgua = (108,110,115)
maxCorAgua = (166,163,162)
i = 0
j = 0

#video = cv2.VideoCapture('TesteVideoMelhor.MOV')
#ret, frame = video.read()
imagem = cv2.imread('PegarPixelsDaAgua.png')

while(i < imagem.shape[1]):
    while(j < imagem.shape[0]):
        if (imagem[i,j] > minCorAgua and imagem[i,j] < maxCorAgua):
            imagem[i,j] = (255,255,255)
    j = j + 1
i = i + 1

cv2.imshow('teste', imagem)
ilyas patanam
  • 5,116
  • 2
  • 29
  • 33
Vagner Garcia
  • 35
  • 1
  • 1
  • 5

1 Answers1

1

Skip to 3 for a numpy solution.

1. Use all

if (all(imagem[i,j] > minCorAgua) and all(imagem[i,j] < maxCorAgua)):

Why? read this answer

When you do imagem[i,j] > minCorAgua, python compares each element of the array imagem[i,j] against each element in minCorAgua and will return an array.

>>>imagem[i,j] > minCorAgua 
array([ True,  True,  True], dtype=bool)
>>>imagem[i,j] < maxCorAgua 
array([ True,  False,  True], dtype=bool)

You cannot do if (a and b) when a and b are lists, arrays, or other iterables, to check if all elements in a and b are true without using the function all. This function will return True if every element of the array is True.

  1. Don't use while use for i in range(imagem.shape[0]):

The range() function will return a list and the for statement will iterate through the list.

>>>range(5)
[0, 1, 2, 3, 4]

Now, you don't need to increment and initialize i and j, making your code cleaner.

for i in range(imagem.shape[1]):
    for j in range(imagem.shape[0]):
        if (all(imagem[i,j] > minCorAgua) and all(imagem[i,j] < maxCorAgua)):
            imagem[i,j] = (255,255,255)

3. A Numpy way to do this

import numpy as np

minCorAgua = (108,110,115)
maxCorAgua = (166,163,162)

bool_pixels = np.all(((imagem>minCorAgua) & (imagem<maxCorAgua)), axis = 2)
imagem[bool_pixels] = (255, 255, 255)
Community
  • 1
  • 1
ilyas patanam
  • 5,116
  • 2
  • 29
  • 33
  • @VagnerGarcia Happy to help, and welcome to Stack Overflow. If this answer or another one solved your issue, please consider [accepting it](http://stackoverflow.com/help/someone-answers) by clicking the checkmark. This indicates to the wider community that you've found a solution and gives some reputation to both the answerer and yourself. There is no obligation to do this. – ilyas patanam Dec 09 '15 at 19:30