OpenCv:翻译图像,将像素环绕边缘(C ++)

时间:2019-09-25 23:07:52

标签: c++ algorithm opencv image-processing

我正在尝试将图像水平转换为x像素,垂直转换为y像素,所以。但是,我希望像素环绕边缘。基本上...

我们从图片一开始...

移动x像素...

并移动y个像素...

据我所知,OpenCv的warpAffine()无法做到这一点。通常,我只需要遍历图像并将像素移动一定量,但是这样做只能将它们水平移动。最有效的方法是什么?

2 个答案:

答案 0 :(得分:4)

您可以使用np.roll()

这是一个可视化

我在Python中实现了它,但是您可以在C ++中应用类似的滚动技术

import cv2
import numpy as np

image = cv2.imread('1.jpg')

shift_x = 800
shift_y = 650

# Shift by x-axis
for i in range(image.shape[1] -1, shift_x, -1):
    image = np.roll(image, -1, axis=1)
    image[:, -1] = image[:, 0]
    cv2.imshow('image', image)
    cv2.waitKey(1)

# Shift by y-axis
for i in range(image.shape[1] -1, shift_y, -1):
    image = np.roll(image, -1, axis=0)
    image[:, -1] = image[:, 0]
    cv2.imshow('image', image)
    cv2.waitKey(1)

cv2.imshow('image', image)
cv2.waitKey()

答案 1 :(得分:3)

从我的角度来看,最“有效”的方法是使用cv::Rect设置四个相应的ROI,然后使用cv::copyTo手动复制内容。也许,也有可能不复制实际内容,而只是指向输入cv::Mat中的数据-但不幸的是,至少我找不到一个。

不过,这是我的代码:

// Shift input image by sx pixels to the left, and sy pixels to the top.
cv::Mat transWrap(cv::Mat& input, const int sx, const int sy)
{
    // Get image dimensions.
    const int w = input.size().width;
    const int h = input.size().height;

    // Initialize output with same dimensions and type.
    cv::Mat output = cv::Mat(h, w, input.type());

    // Copy proper contents manually.
    input(cv::Rect(sx, sy, w - sx, h - sy)).copyTo(output(cv::Rect(0, 0, w - sx, h - sy)));
    input(cv::Rect(0, sy, sx, h - sy)).copyTo(output(cv::Rect(w - sx, 0, sx, h - sy)));
    input(cv::Rect(sx, 0, w - sx, sy)).copyTo(output(cv::Rect(0, h - sy, w - sx, sy)));
    input(cv::Rect(0, 0, sx, sy)).copyTo(output(cv::Rect(w - sx, h - sy, sx, sy)));

    return output;
}

int main()
{
    cv::Mat input = cv::imread("images/tcLUa.jpg", cv::IMREAD_COLOR);
    cv::resize(input, input, cv::Size(), 0.25, 0.25);
    cv::Mat output = transWrap(input, 300, 150);

    return 0;
}

当然,该代码似乎是重复的,但是被包装到一个自己的函数中,它不会打扰您的主代码。 ;-)

输出应该是您想要实现的:

Output

希望有帮助!