2

我想将图像中的每个像素向右移动 1px,下面是我用来进行重映射转换的地图。

这种方法需要比它应该做这样一个简单的转换更多的时间。有我可以使用的 cv 函数吗?还是我只是把图片分成2张图片,一张是src.cols-1像素宽,另一张是1px宽,然后复制到新的图片上?

void update_map()
{
    for( int j = 0; j < src.cols; j++ ){
       for( int i = 0; i < src.rows; i++ ){
         if (j == src.cols-1)
             mat_x_Rotate.at<float>(i,j) = 0;
         else
            mat_x_Rotate.at<float>(i,j) = j + 1;
            mat_y_Rotate.at<float>(i,j) = i;
         }
     }
}
4

2 回答 2

8

你可以做些什么来提高你的表现:

  • 为此目的,重新映射是矫枉过正的。直接复制像素比定义整个重映射转换然后使用它更有效。
  • 切换循环顺序:遍历行,然后是列。(OpenCVMat以行优先顺序存储,因此首先迭代列对缓存非常不友好)
  • 用于Mat::ptr()直接访问同一行中的像素,作为 C 样式数组。(这是一个很大的性能胜利 using at<>(),它可能会检查每次访问的索引)
  • 将您的if语句从内部循环中取出,并0单独处理列。

作为替代方案:是的,如上所述,将图像拆分为多个部分并复制到新图像可能与直接复制一样有效。

于 2012-08-16T19:19:57.597 回答
3
Mat Shift_Image_to_Right( Mat src_in, int num_pixels)
{
    Size sz_src_in = src_in.size();
    Mat img_out(sz_src_in.height, sz_src_in.width, CV_8UC3);

    Rect  roi;
    roi.x = 0;
    roi.y = 0;
    roi.width = sz_src_in.width-num_pixels;
    roi.height = sz_src_in.height;

    Mat crop;

    crop = src_in(roi);

    // Move the left boundary to the right
    img_out =  Scalar::all(0);
    img_out.adjustROI(0, 0, -num_pixels, 0);
    crop.copyTo(img_out);
    img_out.adjustROI(0, 0, num_pixels, 0);

    return img_out;
}
于 2013-07-05T10:21:18.020 回答