Reputation: 47
I am trying to threshold certain values in a grayscale image. So far I have been successful by inputting certain ranges of numbers, but I want to take the values that are between 50 and 150 and multiply them by 1.2. I am not sure how I can access the number within the vector to then multiply it by 1.2.
myimg[myimg <= 50] = 0
myimg[myimg > 150 ] = 255
myimg[50<myimg<=150] = myimg * 1.2 #this line produces this error: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Upvotes: 0
Views: 554
Reputation: 53089
Here are three possible ways to do that.
The first simply multiplies the image by the factor 1.2 and the threshold values by a factor of 1.2 and uses the new threshold values.
The second multiplies the image by the factor 1.2, creates a mask from the threshold value. The uses the mask the to make the image black and white in the desired regions.
The third method does more like what you want without having to process the whole image.
Input (linear gradient image):
import cv2
import numpy as np
# read image as grayscale
img = cv2.imread('grad.png', cv2.COLOR_BGR2GRAY)
# Method 1
# set threshold values
tlow = 50
thigh = 150
# multiply image by 1.2
result1 = img.copy()
result1 = (1.2 * result1).clip(0,255).astype(np.uint8)
# compute modified threshold values
tlow = int(1.2 * tlow)
thigh = int(1.2 * thigh)
result1[result1 <= tlow] = 0
result1[result1 > thigh ] = 255
print(tlow, thigh)
# Method 2
# set threshold values
tlow = 50
thigh = 150
# create mask that is black outside the desired range and white inside the desired range
mask = img.copy()
mask[mask <= tlow] = 0
mask[mask > thigh ] = 255
# modify input by 1.2 factor
result2 = img.copy()
result2 = (1.2 * result2).clip(0,255).astype(np.uint8)
# use mask to combine the input and the modified image
result2[mask==0] = 0
result2[mask==255] = 255
# method 3
# set threshold values
tlow = 50
thigh = 150
result3 = img.copy()
result3[result3 <= tlow] = 0
result3[result3 > thigh ] = 255
result3 = result3.astype(np.float32)
result3[(result3>50) & (result3<=150)] *= 1.2
result3 = result3.clip(0,255).astype(np.uint8)
# save result
cv2.imwrite("grad_process1.png", result1)
cv2.imwrite("grad_mask.png", mask)
cv2.imwrite("grad_process2.png", result2)
cv2.imwrite("grad_process3.png", result3)
# view result
cv2.imshow("result1", result1)
cv2.imshow("mask", mask)
cv2.imshow("result2", result2)
cv2.imshow("result3", result3)
cv2.waitKey(0)
cv2.destroyAllWindows()
Result 1:
Result 2:
Result 3:
Upvotes: 1
Reputation: 142631
Instead of 50<myimg<=150
use
(myimg>50) & (myimg<=150)
and don't foget ()
becuse it will not work.
And you need array with the same size on both sides of =
myimg[(myimg>50) & (myimg<=150)] = myimg[(myimg>50) & (myimg<=150)] * 1.2
or shorter
myimg[(myimg>50) & (myimg<=150)] *= 1.2
Example code
import numpy as np
import random
random.seed(0)
myimg = np.array([random.randint(0, 255) for x in range(10)], float)
print(myimg)
myimg[(myimg>50) & (myimg<=150)] = myimg[(myimg>50) & (myimg<=150)] * 1.2
#myimg[(myimg>50) & (myimg<=150)] = myimg * 1.2
print(myimg)
Upvotes: 2