Shift image content with OpenCV

后端 未结 9 1147
-上瘾入骨i
-上瘾入骨i 2020-12-08 04:36

Starting from an image, I would like to shift its content upward of 10 pixels, without changing size and filling in black the sub image (width x 10px) on the bo

相关标签:
9条回答
  • 2020-12-08 05:10

    Since there's currently no Python solution and a Google search for shifting an image using Python brings you to this page, here's an Python solution using np.roll()


    Shifting against x-axis

    import cv2
    import numpy as np
    
    image = cv2.imread('1.jpg')
    shift = 40
    
    for i in range(image.shape[1] -1, image.shape[1] - shift, -1):
        image = np.roll(image, -1, axis=1)
        image[:, -1] = 0
    
    cv2.imshow('image', image)
    cv2.waitKey()
    

    Shifting against y-axis

    import cv2
    import numpy as np
    
    image = cv2.imread('1.jpg')
    shift = 40
    
    for i in range(image.shape[0] -1, image.shape[0] - shift, -1):
        image = np.roll(image, -1, axis=0)
        image[-1, :] = 0
    
    cv2.imshow('image', image)
    cv2.waitKey()
    
    0 讨论(0)
  • 2020-12-08 05:16

    Here is a function I wrote, based on Zaw Lin's answer, to do frame/image shift in any direction by any amount of pixel rows or columns:

    enum Direction{
        ShiftUp=1, ShiftRight, ShiftDown, ShiftLeft
       };
    
    cv::Mat shiftFrame(cv::Mat frame, int pixels, Direction direction)
    {
        //create a same sized temporary Mat with all the pixels flagged as invalid (-1)
        cv::Mat temp = cv::Mat::zeros(frame.size(), frame.type());
    
        switch (direction)
        {
        case(ShiftUp) :
            frame(cv::Rect(0, pixels, frame.cols, frame.rows - pixels)).copyTo(temp(cv::Rect(0, 0, temp.cols, temp.rows - pixels)));
            break;
        case(ShiftRight) :
            frame(cv::Rect(0, 0, frame.cols - pixels, frame.rows)).copyTo(temp(cv::Rect(pixels, 0, frame.cols - pixels, frame.rows)));
            break;
        case(ShiftDown) :
            frame(cv::Rect(0, 0, frame.cols, frame.rows - pixels)).copyTo(temp(cv::Rect(0, pixels, frame.cols, frame.rows - pixels)));
            break;
        case(ShiftLeft) :
            frame(cv::Rect(pixels, 0, frame.cols - pixels, frame.rows)).copyTo(temp(cv::Rect(0, 0, frame.cols - pixels, frame.rows)));
            break;
        default:
            std::cout << "Shift direction is not set properly" << std::endl;
        }
    
        return temp;
    }
    
    0 讨论(0)
  • Is there a function to perform directly this operation with OpenCV?

    http://code.opencv.org/issues/2299

    or you would do this

      cv::Mat out = cv::Mat::zeros(frame.size(), frame.type());
      frame(cv::Rect(0,10,
      frame.cols,frame.rows-10)).copyTo(out(cv::Rect(0,0,frame.cols,frame.rows-10)));
    

    The code above only can be used to shift to one side (to the left, and to the top). Below code is the extended version of above code which can be used to shift into every direction.

    int shiftCol = 10;
    int shiftRow = 10;
    
    Rect source = cv::Rect(max(0,-shiftCol),max(0,-shiftRow), frame.cols-abs(shiftCol),frame.rows-abs(shiftRow));
    
    Rect target = cv::Rect(max(0,shiftCol),max(0,shiftRow),frame.cols-abs(shiftCol),frame.rows-abs(shiftRow));
    
    frame(source).copyTo(out(target));
    
    0 讨论(0)
提交回复
热议问题