题目要求:
现有一张4通道透明图像a.png。
- 从其中提取出alpha通道并显示;
- 用alpha混合,为a.png替换一张新的背景(背景图自选);
问题一代码:
#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
int main()
{
Mat img = imread("a.png", -1);
Mat mat(img.rows, img.cols, CV_8UC1);
for (int i = 0; i < img.rows; ++i)
{
for (int j = 0; j < img.cols; ++j)
{
mat.at<uchar>(i, j) = img.at<Vec4b>(i, j)[3];
}
}
namedWindow("alpha通道");
imshow("alpha通道", mat);
waitKey();
}
结果如下图:
问题二代码:
#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
int main()
{
Mat img = imread("a.png", -1);
Mat backimg = imread("B.png", -1);
Mat mat(img.rows, img.cols, CV_8UC4);
for (int i = 0; i < img.rows; ++i)
{
for (int j = 0; j < img.cols; ++j)
{
double temp = img.at<Vec4b>(i, j)[3] / 255.00;
mat.at<Vec4b>(i, j)[0] = (1 - temp)*backimg.at<Vec4b>(i, j)[0] + temp*img.at<Vec4b>(i, j)[0];
mat.at<Vec4b>(i, j)[1] = (1 - temp)*backimg.at<Vec4b>(i, j)[1] + temp*img.at<Vec4b>(i, j)[1];
mat.at<Vec4b>(i, j)[2] = (1 - temp)*backimg.at<Vec4b>(i, j)[2] + temp*img.at<Vec4b>(i, j)[2];
mat.at<Vec4b>(i, j)[3] = (1 - temp)*backimg.at<Vec4b>(i, j)[3] + temp*img.at<Vec4b>(i, j)[3];
}
}
namedWindow("alpha合成");
imshow("alpha合成", mat);
waitKey();
}
所选背景B.png如下图:
合成后的图像如下:
我们会发现合成后的图像锯齿现象严重,这是我们将代码中的double temp = img.at<Vec4b>(i, j)[3] / 255
改为double temp = img.at<Vec4b>(i, j)[3] / 255.00
这样就可以消除锯齿了,效果图如下:
锯齿神奇的消失了!这就是数据类型选取的重要性,以后的实验中还会遇到类似的问题。