Search code examples
pythonimage-processingpycharmmappingshearsort

Shear an image in python using Bx and By for forward and backward mapping


I have this problem i would like to have solved. I need to shear an image using forward mapping and then shear it back using backward mapping. The code works if I delete the backMapping but not with it added. Here is my code, any help is appreciated!

import cv2
import numpy as np

img = cv2. imread("Lena2.jpg")

rows, cols, c = img.shape

Bx = 0.2
By = 0.3

def forMap (img,Bx,By):
  rows = img.shape[0]
     cols = img.shape[1]
       imgForward = np.ndarray(shape = (int(cols + rows*By), int(rows + cols*Bx),3))

       for row in range(rows):
         for col in range(cols):
           np.matmul(imgForward,np.array([[rows],[cols]]))
             imgForward[int (row+col*By), int(col+row*Bx)] = img[row,col]/255

        return imgForward

def backMap (img, Bx, By):
  n = int(1/(1-Bx*By))
  rows = img.shape[0]
  cols = img.shape[1]
  imgBackwards = np.ndarray(shape = img.shape);

  for row in range(rows):
    for col in range(cols):
        backCol = int (n*(col+row*Bx))
        backRow = int (n*(col+row*By))
        np.matmul(imgBackwards,np.array([[rows],[cols]]))
        imgBackwards[int(backRow+backCol*By), int(backCol + backRow*Bx)] = img[row,col]

forMap(img, Bx, By)
BackMapping = (backMap(img, Bx, By))

cv2.imshow("original image", img)
cv2.imshow("Forward Mapping", forMap)
cv2.imshow("Backward mapping", backMap)
cv2.waitKey(0)

Solution

  • Forward Mapping:

    order of shape should be (num of rows, num of cols, channnels), so it becomes imgForward = np.ndarray(shape=(int(rows + cols*Bx),int(cols + rows*By),3))

    No need of this line np.matmul(imgForward,np.array([[rows],[cols]]))

    Then, you have to copy all the 3 channels at new position

    imgForward[int(row+col*Bx), int(col+row*By),:] = img[row,col,:]
    

    Backward Mapping

    Only you need to change int(row+col*Bx), int(col+row*By) with int(row-col*Bx), int(col-row*By)

    So your code becomes

    import cv2
    import numpy as np
    
    img = cv2. imread('one.jpg')
    rows, cols, c = img.shape
    
    Bx = 0.2
    By = 0.3
    
    def forMap (img,Bx,By):
        rows = img.shape[0]
        cols = img.shape[1]
        imgForward = np.zeros((int(rows + cols*Bx),int(cols + rows*By),3), dtype=np.ubyte)
        for row in range(rows):
            for col in range(cols):
                #np.matmul(imgForward,np.array([[rows],[cols]]))
                imgForward[int(row+col*Bx), int(col+row*By),:] = img[row,col,:]
    
        return imgForward
    
    def backMap (img, Bx, By):
        rows = img.shape[0]
        cols = img.shape[1]
        imgBackwards = np.zeros(shape=img.shape, dtype=np.ubyte);
    
        for row in range(rows):
            for col in range(cols):
                backCol = int (col-row*By)
                backRow = int (row-col*Bx)
                #np.matmul(imgBackwards,np.array([[rows],[cols],3]))
                imgBackwards[backRow, backCol, :] = img[row,col,:]
        return imgBackwards
    
    fimg = forMap(img, Bx, By)
    bimg = backMap(fimg, Bx, By)
    
    cv2.imshow("original image", img)
    cv2.imshow("Forward Mapping", fimg)
    cv2.imshow("Backward mapping", bimg)
    cv2.waitKey(0)
    cv2.destroyAllWindows()