欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-03-25 14:04:41
...

图像的加载显示

利用图像库的功能,实现从文件加载图像,并在窗口中进行显示的功能;利用常见的图像文件格式(.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替换一张新的背景(背景图自选)
opencv学习系列——图像基本操作
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;
}`

opencv学习系列——图像基本操作
b) 用alpha混合,为a.png替换一张新的背景(背景图自选);
opencv学习系列——图像基本操作
原理:对图像的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;
}

测试截图:
opencv学习系列——图像基本操作
注意问题:

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