opencv学习系列——图像基本操作

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_43943977/article/details/102238746

图像的加载显示

利用图像库的功能,实现从文件加载图像,并在窗口中进行显示的功能;利用常见的图像文件格式(.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;
}

测试截图:
在这里插入图片描述
注意问题:

  1. 格式问题:前景图是给定好的,特别要注意背景图的选取,最简单的是ppt直接制作纯色的背景,这种最为简单;如果想用别的风景之类照,则照片格式的4个通道一定需要都有而且明确,否则会出现内存错误的信息。有的照片不能呈现建议使用Photoshop处理一下即可。
  2. 大小问题,从算法上来看,新建的图片参照前景图大小,这就要求背景图至少比前景图大,才能保证每个像素点就是对应的。

猜你喜欢

转载自blog.csdn.net/weixin_43943977/article/details/102238746