2

我正在寻找一种方法来偏移 OpenCV 的内容,Mat在由于偏移而没有图像的地方添加边框颜色。

void OffsetImage(Mat &image, cv::Scalar bordercolour, int xoffset, int yoffset)
{
    ...
}

如何做到这一点 - 最好不复制输入Mat图像?

4

4 回答 4

3

可能最优雅的方法是使用透视变换:

void OffsetImage(cv::Mat &image, cv::Scalar bordercolour, int xoffset, int yoffset)
{
  if(xoffset != 0 && yoffset != 0)
  {
    cv::Mat H = (cv::Mat_<double>(3,3) << 
      1, 0, xoffset, 0, 1, yoffset, 0, 0, 1);

    cv::Mat aux;
    cv::warpPerspective(image, aux, H, image.size(), cv::INTER_LINEAR, 
      cv::BORDER_CONSTANT, bordercolour);
    image = aux;
  }
}
于 2013-06-17T12:28:43.430 回答
1

就像是:

void OffsetImage(Mat &image, cv::Scalar bordercolour, int xoffset, int yoffset)
{
    Mat temp(image.rows+2*yoffset,image.cols+2*xoffset,image.type(),bordercolour);
    Mat roi(temp(cvRect(xoffset,yoffset,image.cols,image.rows)));
    image.copyTo(roi);
    image=temp.clone();
}
于 2013-06-17T11:19:22.257 回答
1

您将需要以一种或另一种方式复制数据。一旦在 OpenCV 中创建了一个 Mat,你就不能再改变它的大小而不破坏它的内容。

最简单(也是最干净)的方法可能是

void OffsetImage(cv::Mat &image, cv::Scalar bordercolour, int xoffset, int yoffset)
{
   cv::Rect upperRect(xoffset, 0, image.cols, yoffset);
   cv::Rect lowerRect(xoffset, image.rows + yoffset, image.cols, yoffset);
   cv::Rect leftRect(0, yoffset, xoffset, image.cols);
   cv::Rect rightRect(image.cols + xoffset, yoffset, xoffset, image.cols);

   cv::Rect upperLeft(0, 0, xoffset, yoffset);
   cv::Rect upperRight(image.cols + xoffset, 0, xoffset, yoffset);
   cv::Rect lowerLeft(0, image.rows + yoffset, xoffset, yoffset);
   cv::Rect lowerRight(image.cols + xoffset, image.rows + yoffset, xoffset, yoffset);

   cv::Mat nimage(image.rows + xoffset*2, image.cols + yoffset*2, image.type());

   nimage(upperRect).setTo(bordercolour);
   nimage(lowerRect).setTo(bordercolour);
   nimage(leftRect).setTo(bordercolour);
   nimage(rightRect).setTo(bordercolour);

   nimage(upperLeft).setTo(bordercolour);
   nimage(lowerLeft).setTo(bordercolour);
   nimage(upperRight).setTo(bordercolour);
   nimage(lowerRight).setTo(bordercolour);

   image.copyTo(nimage(cv::Rect(xoffset, yoffset, image.cols, image.rows)));
   image = nimage;
}

OpenCV 使用引用计数,因此此清单中的最后一个操作非常便宜。

于 2013-06-17T11:15:50.367 回答
0

此实现允许偏移量在任何方向...

void OffsetImage(Mat &image, cv::Scalar bordercolour, int xoffset, int yoffset)
{
    Mat offsetImage = Mat::zeros(image.size(), image.type());
    padded = Mat(image.rows + 2 * abs(yoffset), image.cols + 2 * abs(xoffset), CV_8UC3, bordercolour);
    image.copyTo(padded(Rect(abs(xoffset), abs(yoffset), image.cols, image.rows)));
    image = Mat(padded, Rect(abs(xoffset) + xoffset, abs(yoffset) + yoffset, image.cols, image.rows));

}
于 2015-07-30T08:38:02.583 回答