Search code examples
pythonrgbbmp

Why does skimage.imread() not return RGB values for my bmp?


I'm trying to slice chunks from a bmp image to use for image correlation, however, when I take a single plane from the array returned by skimage.imread(), instead of getting the red plane or the green plane, I get weird colors, as if the original data is in hsl.

I've tried converting the image to RGB using PIL but the colors just get worse...

Can anyone tell me what's going on?

I'm sure my question needs more info, so let me know what I need to add, please and thanks!

Edit:

from skimage import data
full=data.imread("Cam_1.bmp")
green_template = full[144:194,297:347,1]    #Both give me a sort of reddish square
red_template = full[145:195,252:302,0]

FWIW if skimage.match_template would take color images, I wouldn't have this problem... Is there a correlation library that does color?

Here's the image I'm working with:enter image description here

Here's what results when I display the small crops made with the code above:enter image description here

Also using full = numpy.array(image) after opening with PIL yields the same results.


Solution

  • Ok I figured it out (with the help of a friend).

    I don't totally understand why my pictures were displaying so weirdly, but I do know why they weren't displaying as red and green planes.

    green_template = full[144:194,297:347,1]
    red_template = full[145:195,252:302,0]
    

    These were taking one slice from the final subarray, which would be the g and r values, respectively. What I should have done, if I wanted to display them properly, is create a new image with the green_template and red_template as the respective g and r values, and zeros in the other places, e.g. make it back into an array with shape (width,height,3). For example:

    import Image
    import numpy as np
    
    im = Image.open('Cam_1.bmp')
    #im.show()
    r,g,b = im.split()
    
    y = Image.fromarray(np.zeros(im.size[0]*im.size[1]).reshape(im.size[1],im.size[0]).astype('float')).convert("L")
    
    red = Image.merge("RGB",(r,y,y))
    
    green = Image.merge("RGB",(y,g,y))
    

    If I do that with the original image, here are the images that result:

    enter image description here

    However, my original problem was that skimage's match_template only takes a 2D array. So, it turns out, I had the right arrays the whole time, I just didn't realize that they were right because displaying them results in the weird colors you see in the image in the question. If anyone knows why python does weird things when displaying a 2D image, I'd like to know. Otherwise, I've solved my problem. Thanks to anyone who attempted to help, whether you posted or just tried stuff on your own!

    Edit - requested image rendering code:

    def locate_squares(im):
        r,g,b = im.split()
        red = np.array(r)
        green = np.array(g)
        green_template = green[144:194,297:347]  #,144:194]
        gRadius = (green_template.shape[0]/2, green_template.shape[1]/2)
        red_template = red[145:195,252:302]    #,145:195]
        rRadius = (red_template.shape[0]/2, red_template.shape[1]/2)
        #print red_template
    
        plt.figure(1)
        plt.subplot(1,2,1)
        plt.imshow(green_template)
        plt.subplot(1,2,2)
        plt.imshow(red_template)
    
        plt.figure(2)
        plt.subplot(1,2,1)
        plt.imshow(green)
        plt.subplot(1,2,2)
        plt.imshow(red)
    
        plt.show()