I am working on a basic Image processing task - to conduct pixel based matrix operations given a matrix transformation formula. I am reading through pixel values (gives me a 1*3 tuple) from a (x,y) pixel location in the image and doing matrix operations using numpy, which returns numpy.ndarray's and finally I am required to store the transformed pixel values in a 2d matrix, each (x,y) co-ordinate storing a (1*3) vector of transformed pixel value.

def colortrans(im):
    #(X,Y,Z) = T + [M](*(RGB)(1*3 Vector) 
    # (X,Y,X) = (1*3 tuple) 
    # T = [0,128,128], (a 1*3 vector)
    # M = (3*3 Matrix) 
    # RGB = (1*3 Vector)

    pix = im.load()
    x,y = im.size 
    ycc = []
    #print(ycc.shape)
    m1 = np.array([[0],[128],[128]])
    print(type(m1))
    m2 = np.array([[0.299,0.587,0.114],[-0.168736,-0.331264,0.5],[0.5,-0.418688,-0.081312]])
    print(m2)
    for i in range(x):
        for j in range(y): 
            m = m1.T+np.dot(m2,np.array(pix[i,j]))
            #print(m.shape)
            #print(type(m))
            ycc.append(m)
    #ycc=np.array(ycc)
    print(ycc[1:5])
    mat_ycc = np.reshape(ycc,(x,y))   
    print(len(ycc))
    print (x, y)
    mat_ycc = np.reshape(ycc,(x,y))       
    return  mat_ycc

I want something like this, a format which can be transformed into an image

[(180,128,128),(167,128,128) ... ]

I get this(this format doesn't allow me to reshape as dims doesn't agree)

[array([[180., 128., 128.]]), array([[167., 128., 128.]]), array([[157., 128., 128.]]), array([[178.772   , 127.      , 128.162624]])]

Error I get

len(ycc) = 409600
Image size  = 640*640

The error I get is :

ValueError: cannot reshape array of size 1228800 into shape (640,640)

3 Answers

-1
Ta_Req On

I think you are following a little complicated way. I have little suggestion:

  • Create a U = np.zeroes(x,y,3)

  • apply for loop on 2 dimensional image

    • rgb = select pixel value from all channels
    • ycc = apply the matrix op
    • U[i,j, :] = ycc
1
user2986898 On

You use the pixel count but each pixel constitutes of 3 values, so you should use mat_ycc = np.reshape(ycc,(x,y,3)) # note the ,3 part

0
Community On

Your way could work, but its way too complicated. Why don't you use blockproc as a little helper (I know this since I am in the same lecture)? You could write a simple function that transforms one pixel from RGB to YCbCr and then iterate with said helper over the matrix.

your_matrix = blockproc(your_matrix, (1,3), your_color_transformation)

You could also create a seperate Matrix via numpy.zeros(size) and then write your solutions into the right place. Here you can work with (Y,Cb,Cr) triples. Take every element from the image and process it seperately, create a triple and write it to the correct place.