I am facing a little bit of problem in swapping the channels (specifically red and blue) of an image. I am using Opencv 3.0.0 and Python 2.7.12. Following is my code for swapping the channels
import cv2
img = cv2.imread("input/car1.jpg")
#The obvious approach
Cimg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
#Manual Approach
red = img[:,:,2]
blue = img[:,:,0]
img[:,:,0] = red
img[:,:,2] = blue
cv2.imshow("frame",Cimg)
cv2.imshow("frame2", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
I am unable to figure out why the same image undergoing through the same(probably) operation is giving two different outputs. Can someone throw some light on what's going wrong?
Original Image
Manual Operation
COLOR_BGR2RGB
In OpenCV, BGR sequence is used instead of RGB. This means the first channel is blue, the second channel is green, and the third channel is red. To split an RGB image into different channels, we need to define a matrix of 3 channels. We use 'Mat different_Channels[3]' to define a three-channel matrix.
Image. split() method is used to split the image into individual bands. This method returns a tuple of individual image bands from an image. Splitting an “RGB” image creates three new images each containing a copy of one of the original bands (red, green, blue).
red
and blue
are just views of your image. When you do img[:,:,0] = red
this changes img
but also blue
which is just a view (basically just a reference to the sub-array img[:,:,0]
) not a copy, so you loose the original blue channel values. Basically what you assume is a temp copy just is not. Add .copy()
and it will work.
img = np.arange(27).reshape((3,3,3))
red = img[:,:,2].copy()
blue = img[:,:,0].copy()
img[:,:,0] = red
img[:,:,2] = blue
print("with copy:\n", img)
img = np.arange(27).reshape((3,3,3))
red = img[:,:,2]
blue = img[:,:,0]
img[:,:,0] = red
img[:,:,2] = blue
print("without copy:\n",img)
results:
with copy:
[[[ 2 1 0]
[ 5 4 3]
[ 8 7 6]]
[[11 10 9]
[14 13 12]
[17 16 15]]
[[20 19 18]
[23 22 21]
[26 25 24]]]
without copy:
[[[ 2 1 2]
[ 5 4 5]
[ 8 7 8]]
[[11 10 11]
[14 13 14]
[17 16 17]]
[[20 19 20]
[23 22 23]
[26 25 26]]]
Note: you actually only need 1 temp copy of 1 channel.
Or you could also simply do img[:,:,::-1]
this will create a view again but with swapped channels, img
will stay unchanged, unless you reassign it:
img = np.arange(27).reshape((3,3,3))
print(img[:,:,::-1])
print(img)
img = img[:,:,::-1]
print(img)
results:
[[[ 2 1 0]
[ 5 4 3]
[ 8 7 6]]
[[11 10 9]
[14 13 12]
[17 16 15]]
[[20 19 18]
[23 22 21]
[26 25 24]]]
[[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]]
[[ 9 10 11]
[12 13 14]
[15 16 17]]
[[18 19 20]
[21 22 23]
[24 25 26]]]
[[[ 2 1 0]
[ 5 4 3]
[ 8 7 6]]
[[11 10 9]
[14 13 12]
[17 16 15]]
[[20 19 18]
[23 22 21]
[26 25 24]]]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With