使用OpenCV转换图像内容

vde*_*ris 29 c++ opencv

从图像开始,我想将其内容移动到10个像素的顶部,而不改变大小并width x 10在底部用黑色填充子图像.

例如,原文:

原版的

转移了:

移

有没有使用OpenCV直接执行此操作的功能?

paj*_*_cz 33

您可以简单地使用仿射变换转换矩阵(基本上用于转换点).cv::warpAffine()用适当的变换矩阵就可以了.

TranslationMatrix [1,0,tx;  0,1,TY]

其中: tx在图像x轴上移位, ty在图像y轴上移位,图像中的每个像素都会像这样移动.

您可以使用此函数返回转换矩阵.(这对您来说可能是不必要的)但它会根据offsetxoffsety参数移动图像.

Mat translateImg(Mat &img, int offsetx, int offsety){
    Mat trans_mat = (Mat_<double>(2,3) << 1, 0, offsetx, 0, 1, offsety);
    warpAffine(img,img,trans_mat,img.size());
    return img;
}
Run Code Online (Sandbox Code Playgroud)

在您的情况下 - 您想要将图像向上移10像素,您可以调用:

translateImg(image,0,-10);
Run Code Online (Sandbox Code Playgroud)

然后您的图像将根据您的需要进行移动.

  • 它不只是`Mat_ &lt;double&gt;(2,3)&lt;&lt; 1`。它是整个表达式:`Mat_ &lt;double&gt;(2,3)&lt;&lt; 1,0,offsetx,0,1,offsety`将值插入矩阵。因此,“ trans_mat”中的值在第一行中将为“ 1,0,offsetx”,在第二行中将为“ 0,1,offsety”。如原始帖子中的矩阵“ M”所示。 (2认同)

Zaw*_*Lin 25

有没有使用OpenCV直接执行此操作的功能?

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

或者你会这样做

    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)));
Run Code Online (Sandbox Code Playgroud)

  • @pajus_cz,即使您没有自己创建,也会在任何一种情况下创建"零图像".此外,copyTo执行简单的memcopy操作,该操作比wrapAffine执行的所有复杂操作快得多. (10认同)

小智 10

这个链接也许对这个问题有帮助,谢谢

import cv2
import numpy as np
img = cv2.imread('images/input.jpg')
num_rows, num_cols = img.shape[:2]   

translation_matrix = np.float32([ [1,0,70], [0,1,110] ])   
img_translation = cv2.warpAffine(img, translation_matrix, (num_cols, num_rows))   
cv2.imshow('Translation', img_translation)    
cv2.waitKey()
Run Code Online (Sandbox Code Playgroud)

tx和ty可以分别控制x和y方向上移动像素。

在此输入图像描述


小智 5

这是我根据 Zaw Lin 的回答编写的一个函数,可以按任意数量的像素行或列在任意方向上进行帧/图像移动:

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;
}
Run Code Online (Sandbox Code Playgroud)