分离颜色通道&多通道图像混合
2017-07-12 本文已影响52人
谢小帅
1. split 单通道显示
// 分离颜色通道 split
void splitChannel() {
Mat srcImage = imread("../pictures/bear.jpeg"); // 彩色图像
vector<Mat> channels;
split(srcImage, channels);
for (int i = 0; i < channels.size(); ++i) {
Mat singleChannelImage = channels.at(i);
namedWindow(color[i]);
imshow(color[i], singleChannelImage);
}
}
- 单通道图像没有merge其它通道,就是一个灰度矩阵,所以呈现灰度图
- 由于 RGB值 不同,产生的灰度图也不同
2. merge 多通道图像混合
- 将 logo 图像 merge 底图蓝色通道
- logo 图像 以灰度图像模式 加载
// 多通道混合 merge
void multiChannelBlending() {
// 1.读入图片
Mat logoImage = imread("../pictures/logo.jpg", 0); // flags=0, 灰度图像,GrayScale
Mat srcImage = imread("../pictures/dota.jpg"); // 彩色图像
// 2.把一个3通道图像转换成3个单通道图像
vector<Mat> channels; // vector容器,元素类型:Mat
split(srcImage, channels); // 分离色彩通道
// 3.将原图的 蓝色通道引用 返回给imageBlueChannel
// 注意是引用,相当于两者等价,修改其中一个另一个跟着变
Mat imageBlueChannel = channels.at(0); // RGB 对应 210
// 4.原图蓝色通道ROI 与 logo图 加权操作
// imageBlueChannel是channels.at(0)的引用,所以原图的这个值也跟着变化
Mat srcBlueROI = imageBlueChannel(Rect(500, 250, logoImage.cols, logoImage.rows)); // 选中的是原图的蓝色通道的这一块区域
// srcBlueROI 是蓝色通道值
// logo 是灰度图像,也可以理解为单通道
// logo 图像按照灰度值呈现在蓝色通道中,logoImage如果倍数很大,图像会趋向纯色
addWeighted(srcBlueROI, 1, logoImage, 1000, 0, srcBlueROI);
// 5.将三个单通道重新合并成一个三通道
merge(channels, srcImage); // srcImage更新
// 6.显示效果图
namedWindow("blue");
imshow("blue", srcImage);
}
融合参数
addWeighted(srcBlueROI, 1, logoImage, 1, 0, srcBlueROI);
调整 logoImage 权值为较大值(1000)会 趋于纯色
因为 图像的 RGB 存储类型有上限
addWeighted(srcBlueROI, 1, logoImage, 1000, 0, srcBlueROI);
3. 源代码
#include <cv.h>
#include <highgui.h>
using namespace cv;
using namespace std;
string color[3] = {"Blue", "Green", "Red"}; // 0, 1, 2
// 分离颜色通道 split
void splitChannel() {
Mat srcImage = imread("../pictures/bear.jpeg"); // 彩色图像
vector<Mat> channels;
split(srcImage, channels);
for (int i = 0; i < channels.size(); ++i) {
Mat singleChannelImage = channels.at(i);
namedWindow(color[i]);
imshow(color[i], singleChannelImage);
}
}
// 多通道混合 merge
void multiChannelBlending() {
// 1.读入图片
Mat logoImage = imread("../pictures/logo.jpg", 0); // flags=0, 灰度图像,GrayScale
Mat srcImage = imread("../pictures/dota.jpg"); // 彩色图像
// 2.把一个3通道图像转换成3个单通道图像
vector<Mat> channels; // vector容器,元素类型:Mat
split(srcImage, channels); // 分离色彩通道
// 3.将原图的 蓝色通道引用 返回给imageBlueChannel
// 注意是引用,相当于两者等价,修改其中一个另一个跟着变
Mat imageBlueChannel = channels.at(0); // RGB 对应 210
// 4.原图蓝色通道ROI 与 logo图 加权操作
// imageBlueChannel是channels.at(0)的引用,所以原图的这个值也跟着变化
Mat srcBlueROI = imageBlueChannel(Rect(500, 250, logoImage.cols, logoImage.rows)); // 选中的是原图的蓝色通道的这一块区域
// srcBlueROI 是蓝色通道值
// logo 是灰度图像,也可以理解为单通道
// logo 图像按照灰度值呈现在蓝色通道中,logoImage如果倍数很大,图像会趋向纯色
addWeighted(srcBlueROI, 1, logoImage, 1000, 0, srcBlueROI);
// 5.将三个单通道重新合并成一个三通道
merge(channels, srcImage); // srcImage更新
// 6.显示效果图
namedWindow("blue");
imshow("blue", srcImage);
}
int main() {
splitChannel();
// multiChannelBlending();
waitKey(0);
return 0;
}