国庆期间发现很多小伙伴的头像都换了,添加了国旗的效果,变得更加喜庆。
该效果看上去不难,用 OpenCV 几十行就可以实现了。
最简单的图像融合版本
先来一个最简单的图像融合版本,找一张头像以及一张标准国旗的图片,将找到的头像做裁剪,大小跟国旗的大小保持一致。
icon.jpg然后,两张图片进行叠加
cv::Mat image = cv::imread("/Users/tony/Downloads/icon.jpg");
cv::Mat flag = cv::imread("/Users/tony/Downloads/flag.png");
cv::Mat roi,dst;
cv::imshow("image",image);
cv::imshow("flag",flag);
roi = image(cv::Rect(300,400, flag.cols, flag.rows));
cv::addWeighted(roi, 0.8, flag, 0.35, 0, dst);
cv::imshow("dst",dst);
roi.png
渐变版本
刚才的效果一般,那我们再尝试一下渐变的版本。离红旗越近,红旗的权重越大。这样就可以实现渐变的效果。
cv::Mat image = cv::imread("/Users/tony/Downloads/icon.jpg");
cv::Mat flag = cv::imread("/Users/tony/Downloads/flag.png");
int flag_width = flag.cols;
int flag_height = flag.rows;
Mat roi = image(cv::Rect(450,1200, flag_width, flag_height));
int radius = 0;
if (flag_width > flag_height) {
radius = flag_width;
} else {
radius = flag_height;
}
for (int i=0; i<roi.rows; i++) {
for (int j=0;j<roi.cols;j++) {
int distance = std::sqrt(i*i+j*j);
double alpha;
if (distance > radius) {
alpha = 1;
} else {
alpha = (double) distance / radius;
}
Vec3b v1 = roi.at<Vec3b>(i,j);
roi.at<Vec3b>(i,j)[0]=alpha*v1[0] + (1-alpha)*flag.at<Vec3b>(i,j)[0];
roi.at<Vec3b>(i,j)[1]=alpha*v1[1] + (1-alpha)*flag.at<Vec3b>(i,j)[1];
roi.at<Vec3b>(i,j)[2]=alpha*v1[2] + (1-alpha)*flag.at<Vec3b>(i,j)[2];
}
}
cv::imshow("dst",roi);
result.png
这次的效果,比第一次好多了:)。
btw,祝大家国庆节快乐!
网友评论