我正在寻找一种方法来抵消OpenCV Mat
的内容,添加由于偏移而没有图像的边框颜色。
void OffsetImage(Mat &image, cv::Scalar bordercolour, int xoffset, int yoffset)
{
...
}
如何做到这一点 - 最好不要复制输入Mat
图像?
答案 0 :(得分:2)
可能最优雅的方法是使用透视转换:
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;
}
}
答案 1 :(得分: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使用引用计数,因此此列表中的最后一个操作非常便宜。
答案 2 :(得分: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();
}
答案 3 :(得分: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));
}