Reputation: 1140
I am working on python - Open CV on Ubuntu. I am pretty new in python and I am feeling my coding is not optimized.
The final goal is to change the pixel color to an jpeg image. Let's say that if the red channel value is < 255 I set it at 255.
For that, I transformed the jpeg into a numpy.array. Then using 'for/ in:' loops I go pixel by pixel to check if the red channel is <255. If the condition is met, then I change the value to 255.
My code:
import numpy
import cv2
img=cv2.imread('image.jpeg',1)
y=x=-1 # I use y and x as a counters.
#They will track the pixel position as (y,x)
for pos_y in img:
y=y+1; x=-1 #For each new column of the image x is reset to -1
for pos_x in pos_y:
x=x+1
b, g, r = pos_x # I get the blue, green and red color
# please note that opencv is bgr instead of rgb
if r < 255:
r = 255
pos_x = [b,g,r]
img[y,x] = pos_x
cv2.imshow('Image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
This code works. However, I feel is neither elegant nor efficient.
How could I optimize the code and make it more efficient?
Upvotes: 1
Views: 2748
Reputation: 61415
How about this for an RGB image?
img[img[:, :, 0] < 255, 0] = 255
Using this we create a boolean mask from red channel of the image and check if its value is less than 255. If yes, then we set those values to 255.
OpenCV reads image as BGR
, so:
img[img[:, :, 2] < 255, 2] = 255
would be appropriate.
Alternatively, you could also do:
mask_R = img < 255)[:, :, 2]
img[mask_R, 2] = 255
Example:
In [24]: a
Out[24]:
array([[[168],
[170],
[175]],
[[169],
[170],
[172]],
[[165],
[170],
[174]]])
In [25]: a > 170
Out[25]:
array([[[False],
[False],
[ True]],
[[False],
[False],
[ True]],
[[False],
[False],
[ True]]], dtype=bool)
Using the above condition (a > 170
), we generate a boolean mask. Now, imagine that you take any one of the channels and lay it on top of this boolean mask. And when we assign new values, wherever the mask has true
values, those corresponding elements in the image array will be reset with new value.
# we just filter out the values in array which match our condition
In [36]: a[a > 170]
Out[36]: array([175, 172, 174])
# assign new values. Let's say 180
In [37]: a[a > 170] = 180
In [38]: a
Out[38]:
array([[[168],
[170],
[180]], # <== new value
[[169],
[170],
[180]], # <== new value
[[165],
[170],
[180]]]) # <== new value
Upvotes: 2
Reputation: 53079
If img is an mxnx3 numpy array the following changes the 3rd component in-place:
np.maximum(img[..., 2], 255, out=img[..., 2])
Upvotes: 0