How to extract colour channels from a RGB image - python

I am attempting to separate red, green and blue components of an image and display the resulting images in separate subplots.
To do this, for each colour, I have created an array of zeros the same shape as the original image (using the function np.zeros), and copied one of the image colours across using slicing.
However, the output just appears to be a red square, therefore I don't think the code is working how I would expect it to. Does anyone have any idea where I'm going wrong?
red_image[:,:,0] = red_channel
image = plt.imread('archway.jpg')
plt.imshow(image)
red_channel = image[:,:,0]
red_image = np.zeros(image.shape)
red_image[:,:,0] = red_channel
plt.imshow(red_image)

Related

Is there a way to fill an edge detected image with corresponding colors according to original image?

I am trying to solve an image processing problem.
Here is the input image (figure_1) consists of 3 different colors. the original image has no red or blue which is appended to indicate areas that need to be processed later.
Applying edge detection on figure_1 gets an output image, on which there is only edges and no colors.
here is the code
cv2.namedWindow('Result')
img = cv2.imread('img.png')
v1 = 20
v2 = 20
edges = cv2.Canny(img,v1,v2)
edges = cv2.cvtColor(edges,cv2.COLOR_GRAY2BGR)
res = np.hstack((img,edges))
edges = cv2.Canny(img,v1,v2)
edges = cv2.cvtColor(edges,cv2.COLOR_GRAY2BGR)
res = np.hstack((img,edges))
cv2.imshow('Result',res)
cv2.waitKey()
cv2.destroyAllWindows()
Here is the output image (figure_2), without filling with red or blue, which is the problem needed.
is there a way to fill the figure_2 with corresponding colors (red and blue) according to original image (figure_1) in python?
this piece of code gets me the edge, how can I get the area_red and area_blue separately, so that I can plot different color respectively?
here is the final goal of this task, transfer original raster image (figure_1) to a vector image and filled with lines in corresponding color.
You can try paint the first image in blue and red, then you'll get a image 3 which you can mix with image 2

Python - Image from numpy array losing true pixels

I have a jpg picture of a face, I need to access the picture pixel by pixel (know what value is at each pixel), and use some sort of DFS to change background color.
image = Image.open("pic.jpg")
image = np.array(image)
First of all, why is the shape of the array (473, 354, 3)? It doesn't make sense to me.
When I do
plt.imshow(image.reshape(473, -1))
plt.show()
I get a picture that looks like the following, which consists of only red, blue and yellow colors (and a mixture of the three?)
This means that the values in the array are not what I can reliably use to make my edge detection decisions.
Why and what should I do?
I want the pixel values to reflect the true color of the original image, not like above.
The background in the actual picture is kinda white, and I want them and all other pixel values to stay that way, so I can implement my algorithm.
The 3 is because each color (blue, green red) gets its own entry in the array.
For edge detection, you would might do best to collapse the image down to B&W. OpenCV has cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) that will do the trick.

How to extract green channel from RGB image in Python using Scikit-Image library?

I am extremely new to scikit-image (skimage) library in Python for image processing (started few minutes ago!). I have used imread to read an image file in a numpy.ndarray. The array is 3 dimensional where the size of the third dimension is 3 (namely one for each of Red, Green and Blue components of an image).
rgb_image = imread("input_rgb_image.jpg")
rgb_image.shape # gives (1411L, 1411L, 3L)
I tried to extract green channel as:
green_image = rgb_image[:,:,1]
But when I write this image matrix to an output file as:
imsave("green_output_image.jpg",green_image)
I get an image which doesn't really look ONLY green!
What you are extracting is just a single channel and this shows you how much green colour each pixel has. This will ultimately be visualized as a grayscale image where darker pixels denote that there isn't much "greenness" at those points and lighter pixels denote that there is a high amount of "greenness" at those points.
If I'm interpreting what you're saying properly, you wish to visualize the "green" of each colour. In that case, set both the red and blue channels to zero and leave the green channel intact.
So:
green_image = rgb_image.copy() # Make a copy
green_image[:,:,0] = 0
green_image[:,:,2] = 0
Note that I've made a copy of your original image and changed the channels instead of modifying the original one in case you need it. However, if you just want to extract the green channel and visualize this as a grayscale image as I've mentioned above, then doing what you did above with the setting of your green_image variable is just fine.

Python: Combining images using paste with overlapping pixels and areas with alpha channel=0

I am trying to combine three images together. The image I want on the bottom is a 700x900 image with all black pixels. On top of that I want to paste an image that is 400x400 with an offset of 100,200. On top of that I want to paste an image border that is 700x900. The image border has alpha=0 in the inside of it and alpha=0 around it because it doesn't have straight edges. When I run the code I have pasted below I encounter 2 problems:
1) Everywhere on the border image where the alpha channel = 0, the alpha channel has been set to 255 and the color white shows instead of the black background and the image I am putting the border around.
2) The border image's quality has been significantly reduced and looks a lot different than it should.
Also: part of the border image will cover part of the Image I am putting the border around. So I can't just switch the order that I am pasting.
Thanks in advance for any help.
#!/usr/bin/python -tt
from PIL import ImageTk, Image
old_im2 = Image.open('backgroundImage1.jpg') # size = 400x400
old_im = Image.open('topImage.png') # size = 700x900
new_size = (700,900)
new_im = Image.new("RGBA", new_size) # makes the black image
new_im.paste(old_im2, (100, 200))
new_im.paste(old_im,(0,0))
new_im.show()
new_im.save('final.jpg')
I think you have a misconception about images - the border image does have pixels everywhere. It's not possible for it to be "missing" pixels. It is possible to have an image with an alpha channel, which is a channel like the R, G, and B channels, but indicates transparency.
Try this:
1. Make sure that topImage.png has a transparency channel, and that the pixels that you want to be "missing" are transparent (i.e. have a maximum alpha value). You can double check this way:
print old_im.mode # This should print "RGBA" if it has an alpha channel.
2. Create new_im in "RGBA" mode:
new_im = Image.new("RGBA", new_size) # makes the black image
# Note the "A" --------^
3. Try this paste statement instead:
new_im.paste(old_im,(0,0), mask=old_im) # Using old_im as the mask argument should tell the paste function to use old_im's alpha channel to combine the two images.

PIL Converting an image's hue, then saving out in Python

I'm loading and saving out images with PIL just fine but I can't seem to change the "overall" hue of a given image ~ google and here revealed an answer, sort of, with the numpy module, but thats not an option for me
It should be quite simple, given a gray image with alpha, I'd like to make it's hue red
I think you want a mono-hue image. Is this true?
It's not clear what you want done with the existing bands (alpha and greyscale/level). Do you want alpha to remain alpha and the greyscale to become red saturation? Do you want the alpha to become your red saturation? Do you want greyscale to be the image lightness and the alpha to become the saturation?
Edit:
I've changed the output based on your comment. You wanted the darkest shade of the greyscale band to represent fully saturated red and the lightest grey to represent white (in other words full-saturated with all colors). You also indicated that you wanted alpha to be preserved as alpha in the output. I've made that change too.
This is possible with some band swapping:
import Image
# get an image that is greyscale with alpha
i = Image.open('hsvwheel.png').convert('LA')
# get the two bands
L,A = i.split()
# a fully saturated band
S, = Image.new('L', i.size, 255).split()
# re-combine the bands
# this keeps tha alpha channel in the new image
i2 = Image.merge('RGBA', (S,L,L,A))
# save
i2.save('test.png')

Categories