【发布时间】:2021-12-19 11:02:20
【问题描述】:
我有 2 张透明图片。图像具有相同的格式和大小。 如何使用 C++ OpenCV 将像素从第二个图像复制到第一个图像? 这个想法是在第一张图像上绘制第二张图像。
谢谢
【问题讨论】:
-
请贴出你试过的代码。
-
谢谢@L.ScottJohnson 这正是我所需要的!
我有 2 张透明图片。图像具有相同的格式和大小。 如何使用 C++ OpenCV 将像素从第二个图像复制到第一个图像? 这个想法是在第一张图像上绘制第二张图像。
谢谢
【问题讨论】:
来自上述评论链接的代码(针对我的情况进行了修改) L. Scott Johnson 再次感谢您!
void alphaBlend(Mat& foreground, Mat& background, Mat& alpha, Mat& outImage)
{
// Find number of pixels.
int numberOfPixels = foreground.rows * foreground.cols * foreground.channels();
// Get floating point pointers to the data matrices
float* fptr = reinterpret_cast<float*>(foreground.data);
float* bptr = reinterpret_cast<float*>(background.data);
float* aptr = reinterpret_cast<float*>(alpha.data);
float* outImagePtr = reinterpret_cast<float*>(outImage.data);
// Loop over all pixesl ONCE
for (
int i = 0;
i < numberOfPixels;
i++, outImagePtr++, fptr++/*, aptr++*/, bptr++
)
{
if (i!= 0 && (i % 3) == 0)
aptr++;
*outImagePtr = (*fptr) * (*aptr) + (*bptr) * (1 - *aptr);
}
}
void Mix()
{
Mat layer = imread("images\\leyer.png", IMREAD_UNCHANGED);
Mat image = imread("images\\bg.jpg");
std::vector<cv::Mat> bgra_planes;
cv::split(layer, bgra_planes);
Mat alpha = bgra_planes[3];
bgra_planes.pop_back();
cv::merge(bgra_planes, layer);
alpha.convertTo(alpha, CV_32FC3, 1.0 / 255);
layer.convertTo(layer, CV_32FC3);
image.convertTo(image, CV_32FC3);
Mat result(layer.size(), CV_32FC3);
alphaBlend(layer, image, alpha, result);
result.convertTo(result, CV_8UC3);
// previous tries
//cv::copyTo(layer, image, );
//cv::addWeighted(image, 1, layer, 1, 0.5, result);
String windowName = "alpha blending";
namedWindow(windowName, WINDOW_NORMAL);
imshow(windowName, result);
waitKey(0);
destroyWindow(windowName);
}
【讨论】:
cv::Mat::at<>() 存在是有原因的。
您可以尝试以下方法:
加载您的第一张图片
cv::Mat img = cv::imread("img.jpeg");
找到你的小图片 - 我只是在调整同一张图片的大小
cv::Mat img_resize;
cv::resize(img, img_resize, cv::Size(), 0.3, 0.3);
选择 xy 原点位置
const cv::Point origin(100, 100);
创建一个感兴趣的区域
cv::Rect roi(origin, img_resize.size());
复制矩阵数据
img_resize.copyTo(img(roi));
【讨论】: