OpenCV giving wrong color to colored images on loading
OpenCV uses BGR as its default colour order for images, matplotlib uses RGB. When you display an image loaded with OpenCv in matplotlib the channels will be back to front.
The easiest way of fixing this is to use OpenCV to explicitly convert it back to RGB, much like you do when creating the greyscale image.
RGB_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
And then use that in your plot.
Wrong color reading an image with OpenCV (Python)
OpenCV does not use RGB, it uses BGR (standing for blue, green, red). You need to swap the order of the red and the blue.
img1 = cv2.imread("tiger.jpg", 3)
b,g,r = cv2.split(img1) # get b, g, r
rgb_img1 = cv2.merge([r,g,b]) # switch it to r, g, b
plt.subplot(121),plt.imshow(rgb_img1),plt.title('TIGER_COLOR')
Also, your grayscale image is fine, but you are using a colormap for it. Make sure to use
plt.imshow(img2, cmap='gray')
imshow colored image, wrongly displayed as blue
The problem is that opencv uses bgr
color mode and matplotlib uses rgb
color mode. Therefore the red and blue color channels are switched.
You can easily fix that problem by proving matplotlib an rgb image or by using cv2.imshow
function.
BGR to RGB conversion:
for im in images:
# convert bgr to rgb
rgb = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
plt.imshow(rgb, cmap = plt.cm.Spectral)opencv's imshow function:
for im in images:
# no color conversion needed, because bgr is also used by imshow
cv2.imshow('image',im)
wrong colors when saving image with openCV
As @fmw42 pointed at me in the question comments section,
I was calling np.array()
on mss ScreenShot
objects and expecting them to it to work out of the box.
It turns out ScreenShot
class stores image data on a specific format, and when np.array()
manipulates an instance object, it uses a different format for managing image channels, specifically the alpha channel.
So the solution was to first convert mss ScreenShot
objects in Image
objects that hold image data in compatible way for np.array()
to handle them :
def find_diff(before, after):
before = Image.frombytes("RGB", before.size, before.bgra, "raw", "BGRX")
after = Image.frombytes("RGB", after.size, after.bgra, "raw", "BGRX")
before = np.array(before)
after = np.array(after)
...
Image changes color when using cv2 imread
The cv2
module reads in images in BGR format, while the matplotlib
module uses RGB. A simple fix would be to use the cv2.cvtColor()
method on the image first:
auxImgRGB = cv2.cvtColor(auxImg, cv2.COLOR_BGR2RGB)
The COLOR_BGR2RGB
mode is 4
.
Displayed image from a time frame of a video has the wrong color
OpenCV uses BGR as its default colour order for images
Use cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
before displaying
why cv2.imwrite() changes the color of pics?
Your problem is in the fact that skimage.io.imread
loads image as RGB (or RGBA), but OpenCV assumes the image to be BGR or BGRA (BGR is the default OpenCV colour format). This means that blue and red planes get flipped.
3 Channel Images
Let's try this out with the following simple test image:
First let's try your original algorithm:
import skimage.io
import cv2
img = skimage.io.imread('sample.png')
cv2.imwrite('sample_out_1.png', img)
We get the following result:
As you can see, red and blue channels are visibly swapped.
The first approach, assuming you want to still use skimage to read and cv2 to write is to use cv2.cvtColor
to convert from RGB to BGR.
Since the new OpenCV docs don't mention Python syntax, in this case you can also use the appropriate reference for 2.4.x.
import skimage.io
import cv2
img = skimage.io.imread('sample.png')
cv2.imwrite('sample_out_2.png', cv2.cvtColor(img, cv2.COLOR_RGB2BGR))
Now we get the following output:
An alternative is to just use OpenCV -- use cv2.imread
to load the image. In this case we're working only with BGR images.
NB: Not providing any flags means cv2.IMREAD_COLOR
is used by default -- i.e. image is always loaded as a 3-channel image (dropping any potential alpha channels).
import cv2
img = cv2.imread('sample.png')
cv2.imwrite('sample_out_3.png', img)
4 Channel Images
From your screenshot, it appears that you have a 4 channel image. This would mean RGBA in skimage, and BGRA in OpenCV. The principles would be similar.
- Either use colour conversion code
cv2.COLOR_RGBA2BGRA
- Or use
cv2.imread
with flagcv2.IMREAD_UNCHANGED
Can't get same color of original image when saving same image in OpenCv, Python
I could solve the problem. I have to convert color of image into RGB color.
cv2.cvtColor(rotate_img, cv2.COLOR_BGR2RGB)
Here is the code :
from scipy.ndimage import rotate
from scipy.misc import imread, imshow
import cv2
count = 0
while True:
if count<230:
filename = 'frame'+str(count)+'.jpg'
print(filename)
img = imread(filename)
rotate_img = rotate(img, 90)
#convert color of image before saving
rgbImg = cv2.cvtColor(rotate_img, cv2.COLOR_BGR2RGB)
cv2.imwrite(filename,rgbImg)
count = count + 1
continue
else :
break
Related Topics
How to Execute Raw SQL in Flask-Sqlalchemy App
What Is the Pythonic Way to Avoid Default Parameters That Are Empty Lists
How to Use the Same Python Virtualenv on Both Windows and Linux
Connect Wifi with Python or Linux Terminal
Circular Shift of Vector (Equivalent to Numpy.Roll)
Using Strides for an Efficient Moving Average Filter
Python Date String to Date Object
Googletrans Stopped Working with Error 'Nonetype' Object Has No Attribute 'Group'
How to Write a Python Module/Package
Disable Tensorflow Debugging Information
Pandas: Convert Categories to Numbers
How to Make a Multi-Color Line in Matplotlib
Convert Unicode to Ascii Without Errors in Python
Locale Date Formatting in Python
What Is the Purpose of a Backslash at the End of a Line
How to Add Multiple Columns to Pandas Dataframe in One Assignment
Pandas Dataframe: Replace Nan Values with Average of Columns