1
image = cv2.imread('black.jpg')[:,:,0] # let's just take the red channel alone for brevity
print(image[75:85,155:165]) # print middle 10x10
# output: [[0,0,0,....],...]

I want subtract 1 from all pixel intensity. And yes, I definitely do not want 0s to become 255s. I just want them to stay as 0.

print(image[75:85,155:165]-1)
# output: [[255,255,255,....],...]

print(np.array(image[75:85,155:165])-1)
# output: [[255,255,255,....],...]

print(np.array(image[75:85,155:165], dtype='float32')-1)
# output: [[-1.,-1.,-1.,....],...]

I can convert the last one back to uint8 after .clip(0,255) but that doesn't feel like the right way of doing it. Is there a way to directly do it (without casting and if conditions which might not be efficient for parallel processing)?

Saravanabalagi Ramachandran
  • 8,551
  • 11
  • 53
  • 102

3 Answers3

2

The best way to do it is np.where with mask:

grey_new = np.where(image == 0, 0, image - 1)

more info you can find in this answer, and numpy.where documentation.

ykaner
  • 1,740
  • 1
  • 9
  • 13
0

One easy option would be:

image[75:85,155:165] - 1 * (image[75:85,155:165] > 0)
jdehesa
  • 58,456
  • 7
  • 77
  • 121
0

Since you remove 1 to all values, only the 0 values will become 255. What you can do, then, is simply to put those back to 0 :

a = np.array(image[75:85,155:165])-1
a[a==255] = 0
Ben
  • 441
  • 3
  • 10