赞
踩
这个是我自己做的粗略的螺旋丸的图,导出为png并带有alpha通道。
最后和一只狗合成成这个样子。
效果还是可以的。
为了实现这个效果,首先我们要明白具有透明通道的图片的opencv的读取方式。在OpenCV里,正常是读取图像和写入图像默认都是忽略透明通道的,如果想要读取原图像中的透明通道,则在使用imread()
函数时,后面的参数要使用CV_LOAD_IMAGE_UNCHANGED
参数或是直接写-1也可以。比如:
- Mat inimg = imread("dog.png", CV_LOAD_IMAGE_UNCHANGED); // 读取透明通道
- // 输出RGBA数值
- cout << (int)inimg.at<Vec4b>(0,0)[0] << endl
- << (int)inimg.at<Vec4b>(0,0)[1] << endl
- << (int)inimg.at<Vec4b>(0,0)[2] << endl
- << (int)inimg.at<Vec4b>(0,0)[3] << endl;
这样我们读取的图片就有了四个通道,也就是BGRA四个通道,第四个就是Alpha通道,这个通道通过0-255的数值来代表该像素的透明度。
- #include <vector>
- #include <stdio.h>
- #include <opencv2/opencv.hpp>
-
- using namespace cv;
- using namespace std;
-
- int cvAdd4cMat_q(cv::Mat &dst, cv::Mat &scr, double scale);
-
- int main()
- {
- char str[16];
- Mat img1 = imread("bk.jpg"), img2 = imread("img.png", -1);
- Mat img1_t1(img1, cvRect(0, 0, img2.cols, img2.rows));
- cvAdd4cMat_q(img1_t1,img2,1.0);
- imshow("final",img1);
- waitKey(0);
- return 0;
- }
-
- int cvAdd4cMat_q(cv::Mat &dst, cv::Mat &scr, double scale)
- {
- if (dst.channels() != 3 || scr.channels() != 4)
- {
- return true;
- }
- if (scale < 0.01)
- return false;
- std::vector<cv::Mat>scr_channels;
- std::vector<cv::Mat>dstt_channels;
- split(scr, scr_channels);
- split(dst, dstt_channels);
- CV_Assert(scr_channels.size() == 4 && dstt_channels.size() == 3);
-
- if (scale < 1)
- {
- scr_channels[3] *= scale;
- scale = 1;
- }
- for (int i = 0; i < 3; i++)
- {
- dstt_channels[i] = dstt_channels[i].mul(255.0 / scale - scr_channels[3], scale / 255.0);
- dstt_channels[i] += scr_channels[i].mul(scr_channels[3], scale / 255.0);
- }
- merge(dstt_channels, dst);
- return true;
- }
最终使用这个方法,可以到达前图的效果。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。