How delete channel in image opencv - python

I i have two different images(frames of video):
first image:
print(img1.shape)
(31,27,3)
second image:
print(img2.shape)
(31,27)
How i can delete on first image the value 3?

img1.shape variable returns height, width, channel of your current image.
How i can delete on first image the value 3?
3 refers to BGR channel in your image.
(I assume you read the image using cv2.imread)
You can convert to the gray-scale by
img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
Now print(img1.shape)
and result will be:
(31, 27)

The 3 means that you have an RGB image, a color image.
If you want to make it grayscale, as I guess your second image is, use
from skimage import color
gray_image = color.rgb2gray(image)

Related

Converting Color Images to Grayscale but shape of the image stays identical

I've converted some images from RGB to Grayscale for ML purpose.
However the shape of the converted grayscale image is still 3, the same as the color image.
The code for the Conversion:
from PIL import Image
img = Image.open('path/to/color/image')
imgGray = img.convert('L')
imgGray.save('path/to/grayscale/image')
The code to check the shape of the images:
import cv2
im_color = cv2.imread('path/to/color/image')
print(im_color.shape)
im_gray2 = cv2.imread('path/to/grayscale/image')
print(im_gray2.shape)
You did
im_gray2 = cv2.imread('path/to/grayscale/image')
OpenCV does not inspect colorness of image - it does assume image is color and desired output is BGR 8-bit format. You need to inform OpenCV you want output to be grayscale (2D intensity array) as follows
im_gray2 = cv2.imread('path/to/grayscale/image', cv2.IMREAD_GRAYSCALE)
If you want to know more about reading images read OpenCV: Getting Started with Images
cv.imread, without any flags, will always convert any image content to BGR, 8 bits per channel.
If you want any image file, grayscale or color, to be read as grayscale, you can pass the cv.IMREAD_GRAYSCALE flag.
If you want to read the file as it really is, then you need to use cv.IMREAD_UNCHANGED.
im_color = cv2.imread('path/to/color/image', cv2.IMREAD_UNCHANGED)
print(im_color.shape)
im_gray2 = cv2.imread('path/to/grayscale/image', cv2.IMREAD_UNCHANGED)
print(im_gray2.shape)

Why does the grayscale image converted by cv2 still have 3 channels?

I encountered this puzzling situation when trying to get rid of the third dimension (the RGB dimension) of my images in order to feed them to a Knn classifier for face recognition.
I took one colored face image from the Labeled-face-in-the-wild database as an example. It is saved locally.
I first imported the image, then converted it to grayscale, then checked dimension (time1), then exported with "imwrite", then imported the gray scale image again, then checked its dimension again (time2).
At (time1), the dimension was 2: (250, 250). However, at (time2), the dimension became 3: (250, 250, 3). Why would exporting and importing change the dimension of the gray scale picture? What should I specify when importing the gray scale picture to keep it 2 dimensional?
Here is my python code:
import cv2
import matplotlib.pyplot as plt
imgBGR = cv2.imread("path/filename")
gray = cv2.cvtColor(imgBGR, cv2.COLOR_BGR2GRAY)
gray.shape # this gives me (250, 250)
cv2.imwrite("path/newname", gray)
gray2 = cv2.imread("path/newname")
gray2.shape # this gives me (250, 250, 3)
Try gray2 = cv2.imread("path/newname" , cv2.IMREAD_GRAYSCALE)
As Opencv imread documentaion, the default is cv2.IMREAD_COLOR, so with setting the flag the default setting of cv2.imread is reading image in colour, so it will split a greyscale image into 3 channels.
By specific cv2.imread("path/newname" , cv2.IMREAD_GRAYSCALE), the function will read in image in grayscale.

Converting image to grayscale

I want to convert any image to grayscale, but I don't understand the difference between these implementations.
image = cv2.imread('lenna.jpg')
gray = cv2.cvtColor(image, cv2.IMREAD_GRAYSCALE)
gray1 = rgb2gray(image)
gray2 = cv2.imread('lenna.jpg', cv2.IMREAD_GRAYSCALE)
image1 = Image.open('lenna.jpg', 'r')
gray3 = image1.convert('L')
When I plot them, I get them in blue scale, green scale, green scale and gray respectively. When I should use each one?
You've encountered a spot where Python's type system isn't protecting you in the way that C++ would.
cv2.IMREAD_GRAYSCALE and cv2.COLOR_BGR2GRAY are values from different enumerations. The former, whose numerical value is 0, applies to cv2.imread(). The latter, whose numerical value is 6, applies to cv2.cvtColor(). C++ would have told you that cv2.IMREAD_GRAYSCALE can't be passed to cv2.cvtColor(). Python quietly accepts the corresponding int value.
Thus, you think you're asking cv2 to convert a color image to gray, but by passing cv2.IMREAD_GRAYSCALE, cv2.cvtColor() sees the value 0, and thinks you're passing cv2.COLOR_BGR2BGRA. Instead of a grayscale image, you get the original image with an alpha channel added.
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
is what you need instead.
The other issue you're seeing, assuming you're using a Jupyter notebook, is that cv2 layers color planes in BGR order instead of RGB. To display them properly, first do
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
and then display the result.
The images that are not gray are the still 3d arrays, that is to say they still somehow retain color information, the reason you are seeing blue and green is because in those 3d arrays the red and green channels in the first case and the blue & red channels in the second have been reduced to 0 leaving only the blue and green that you see.
In order to read the image as grayscale you would use
img_gray=cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
This will yield a 2d array with values between 0 and 255 corresponding to how bright the pixel should be instead of how bright each of the 3 color channels of the pixel should be.

Convert RGB image to YUV and YCbCr color space image in Opencv Python

Can anyone help me to convert an RGB colour space image to YUV colour space image and to YCbCr colour space image using opencv Python?
Use cv2.cvtColor(src, code) to convert Color-Space, the code starts with COLOR_.
You can use this to look for the color code.
import cv2
## get all color codes
codes = [x for x in dir(cv2) if x.startswith("COLOR_")]
## print first three color codes
print(codes[:3])
# ['COLOR_BAYER_BG2BGR', 'COLOR_BAYER_BG2BGRA', 'COLOR_BAYER_BG2BGR_EA']
## print all color codes
print(codes)
If you read the image into BGR space, then use cv2.COLOR_BGR2YUV and cv2.COLOR_BGR2YCrCb:
#cv2.COLOR_BGR2YUV
#cv2.COLOR_BGR2YCrCb
img = cv2.imread("test.png")
yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YUV)
cv2.imwrite("yuv.png", yuv)
If you read the image into RGB space, then use cv2.COLOR_RGB2YUV and cv2.COLOR_RGB2YCrCb.
Here is an example image(in BGR-HSV-YUV-YCRCB color spaces):

Adding an alpha channel to a Monochrome Image using Open CV Python

I have been working on colour images(RGB) and color images with an alpha channel(RGBA) . Reading an alpha channel from an RGBA image is pretty easy and I can even split the 4 channels of the image. Is there any method by which I can add an alpha channel to a monochrome or a grayscale image? Also, can alpha channel be separately added to the R,G,B Channels individually ?
The code I am using to read a transparent image and split the channels is as follows -
import cv2
img = cv2.imread(image1_path,-1)
b = img[:,:,0]
g = img[:,:,1]
r = img[:,:,2]
a = img[:,:,3]
img_merge = cv2.merge((b,g,r,a))
cv2.imshow("img_merge",img_merge)
cv2.imshow("r channel",r)
cv2.imshow("g channel",g)
cv2.imshow("b channel",b)
cv2.imshow("a channel",a)
cv2.waitKey(0)
cv2.destroyAllWindows()
The image I am using is -
You cannot create a 2-channel "luminance-alpha" image, however you can convert the 1-channel grayscale image to BGRA using only gray values by duplicating the grayscale channel and adding the alpha channel to that. Let l be the grayscale image:
img_3gray = cv2.merge((l,l,l,a))
Nor can you apply an alpha channel to just one channel of an image, but you can take a single channel of the image (say, blue) and turn it into a grayscale image as we did before:
img_3blue = cv2.merge((b,b,b,a))
or you can display only the blue channel with alpha:
img_bzz = cv2.merge((b,z,z,a))
where z is all zeroes.

Categories