opencv学习系列——图像基本操作
图像的加载显示
利用图像库的功能,实现从文件加载图像,并在窗口中进行显示的功能;利用常见的图像文件格式(.jpg; .png; .bmp; .gif等)进行测试;
这个很简单,大家一看程序就懂了
#include<opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
Mat src = imread("D:/picture/a.png");
Mat dst;
//cvtColor(src, dst, COLOR_RGB2GRAY, 1);//去色
namedWindow("src", WINDOW_NORMAL);
imshow("src",src);
waitKey();//保持输出图像不消失
return 0;
}
这段代码是最基本的,要记住加载图像代码
Mat src = imread(Path);
和显示代码
namedWindow(“src”, WINDOW_NORMAL);
imshow(“src”,src);
waitKey();这一行必须有,起作用是保持图像显示在屏幕上,否则会出现闪退。
Mat是最基本的定义符合,它定义一个像素矩阵,读取图像后图像的每一个像素信息就会存到这个矩阵里面。
注:gif格式不能这样读取
图像合成
现有一张4通道透明图像a.png: 从其中提取出alpha通道并显示; 用alpha混合,为a.png替换一张新的背景(背景图自选)
a) 从其中提取出alpha通道并显示;
原理:创建一个8位无符号的单通道照片用来存储alpha通道,将原来的照片每个像素点的值对应到新的照片矩阵中即可。
Alpha
在图像处理中,Alpha用来衡量一个像素或图像的透明度。在非压缩的32位RGB图像中,每个像素是由四个部分组成:一个Alpha通道和三个颜色分量(R、G和B)。当Alpha值为0时,该像素是完全透明的,而当Alpha值为255时,则该像素是完全不透明。
Alpha混色是将源像素和背景像素的颜色进行混合,最终显示的颜色取决于其RGB颜色分量和Alpha值。它们之间的关系可用下列公式来表示:
显示颜色 = 源像素颜色 X alpha / 255 + 背景颜色 X (255 - alpha) / 255
创建图像矩阵的格式
CV_<bit_depth>(S|U|F)C<number_of_channels>
(1)–bit_depth—比特数—代表8bite,16bites,32bites,64bites,如
如果你现在创建了一个存储–灰度图片的Mat对象,这个图像的大小为宽100,高100,那么,现在这张灰度图片中有10000个像素点,它每一个像素点在内存空间所占的空间大小是8bite,8位–所以它对应的就是CV_8。
(2)–S|U|F–S--代表—signed int—有符号整形
U–代表–unsigned int–无符号整形
F–代表–float---------单精度浮点型
(3)–C<number_of_channels>----代表—一张图片的通道数,比如:
1–灰度图片–grayImg—是–单通道图像
2–RGB彩色图像---------是–3通道图像
typedef Vec <uchar, 2> Vec2b;
Vec2b—表示每个Vec2b对象中,可以存储2个char(字符型)数据
Vec3b—表示每一个Vec3b对象中,可以存储3个char(字符型)数据,比如可以用这样的对象,去存储RGB图像中的
Vec4b—表示每一个Vec4b对象中,可以存储4个字符型数据,可以用这样的类对象去存储—4通道RGB+Alpha的图。
核心代码:
mat.at(i, j) = img.at(i, j)[3];
bl80Mzk0Mzk3Nw==,size_16,color_FFFFFF,t_70)`#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
int main()
{
Mat img = imread("D:/picture/a.png", -1);//-1使能读取第4个RGBA中的A通道,即为alpha通道
Mat mat(img.rows, img.cols, CV_8UC1);//可以创建----8位无符号的单通道---灰度图片------grayImg
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();
return 0;
}`
b) 用alpha混合,为a.png替换一张新的背景(背景图自选);
原理:对图像的alpha通道进行处理,如果值为0,说明色素透明,此处填充背景颜色;否则填充图像颜色,所以对创建新的像素矩阵,对每一个像素点进行按比例分配前景图和背景图的像素点即可。
核心代码:
double temp = img.at(i, j)[3] / 255.00;
mat.at(i, j) = (1 - temp) * backimg.at(i, j) + temp * img.at(i, j);
#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
int main()
{
Mat img = imread("D:/picture/aa.png",-1);
Mat backimg = imread("D:/picture/ee.png",-1);
Mat mat(img.rows, img.cols, CV_8UC4);//创建8为4通道照片
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();
return 0;
}
测试截图:
注意问题:
- 格式问题:前景图是给定好的,特别要注意背景图的选取,最简单的是ppt直接制作纯色的背景,这种最为简单;如果想用别的风景之类照,则照片格式的4个通道一定需要都有而且明确,否则会出现内存错误的信息。有的照片不能呈现建议使用Photoshop处理一下即可。
- 大小问题,从算法上来看,新建的图片参照前景图大小,这就要求背景图至少比前景图大,才能保证每个像素点就是对应的。
上一篇: 第二十章:商品详情与页面静态化