栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

图像基本操作---Opencv&&C++

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

图像基本操作---Opencv&&C++

目录
  • 一.图像的读写
    • 1.读取图像
    • 2.显示图像
  • 二.图像格式转换
    • 1.彩色图像转为灰度图像
    • 2.灰度图像转为二值图像
  • 三.图像取反
  • 四.图像镜像
  • 五.图像旋转
  • 六.获取图像部分内容
  • 七.图像信息隐藏和恢复
  • 八.完整代码

一.图像的读写 1.读取图像
Mat src = imread("image_path");

注意:路径应使用 \
例如:C:\images\****.jpg

2.显示图像
imshow("原图", src);

显示imread读取的图像,并在“原图”窗口显示。

二.图像格式转换 1.彩色图像转为灰度图像

(1)调用Opencv函数

Mat dst0;
cvtColor(src, dst0, CV_BGR2GRAY);

(2)最大亮度转换
取RGB最大值的方法生成灰度图。

int b = src.at(row, col)[0];  //b通道
int g = src.at(row, col)[1];  //g通道
int r = src.at(row, col)[2];  //r通道
//最大亮度转换:取rgb最大值的方法生成灰度图
dst1.at(row, col)[0] = max(r, max(g, b));
dst1.at(row, col)[1] = max(r, max(g, b));
dst1.at(row, col)[2] = max(r, max(g, b));

(3)最小亮度转换
取RGB最小值的方法生成灰度图。

//最小亮度转换:取rgb最小值的方法生成灰度图
dst2.at(row, col)[0] = min(r, min(g, b));
dst2.at(row, col)[1] = min(r, min(g, b));
dst2.at(row, col)[2] = min(r, min(g, b));

(4)平均亮度转换
取RGB平均值的方法生成灰度图。

//平均亮度转换:取rgb平均值的方法生成灰度图
dst3.at(row, col)[0] = (r + g + b) / 3;
dst3.at(row, col)[1] = (r + g + b) / 3;
dst3.at(row, col)[2] = (r + g + b) / 3;

(5)亮度优先转换(最大最小值平均)

//亮度优先转换
dst4.at(row, col)[0] = (max(r, max(g, b)) + min(r, min(g, b))) / 2;
dst4.at(row, col)[1] = (max(r, max(g, b)) + min(r, min(g, b))) / 2;
dst4.at(row, col)[2] = (max(r, max(g, b)) + min(r, min(g, b))) / 2;

(6)权重亮度转换
给RGB分别赋予不同的权重,且权重值相加和为1。

//权重亮度转换
dst5.at(row, col)[0] = 0.21 * r + 0.72 * g + 0.07 * b;
dst5.at(row, col)[1] = 0.21 * r + 0.72 * g + 0.07 * b;
dst5.at(row, col)[2] = 0.21 * r + 0.72 * g + 0.07 * b;


2.灰度图像转为二值图像

通过设置阈值来指定不同范围内像素的值为0或255。

//灰度图变为二值图像,采用平均亮度转换的灰度图像,阈值设为128
if (dst3.at(row, col)[0] <= 128)
{
	dst6.at(row, col)[0] = 0;
	dst6.at(row, col)[1] = 0;
	dst6.at(row, col)[2] = 0;
}
else
{
	dst6.at(row, col)[0] = 255;
	dst6.at(row, col)[1] = 255;
	dst6.at(row, col)[2] = 255;
}

三.图像取反

(1)遍历像素矩阵,使用255-pix_value(像素值)进行取反。

for (int row = 0; row < src.rows; row++)
	{
		for (int col = 0; col < src.cols; col++)
		{
			//彩色图片
			int b = src.at(row, col)[0];  //b通道
			int g = src.at(row, col)[1];  //g通道
			int r = src.at(row, col)[2];  //r通道

			dst7.at(row, col)[0] = 255-b;
			dst7.at(row, col)[1] = 255-g;
			dst7.at(row, col)[2] = 255-r;
		}
	}

(2)对图像整体做减法

Mat dst7_1 = Scalar(255, 255, 255) - src;

Scalar():定义一个矩阵并对其附上颜色。
也可以使用subtract()函数进行减法运算:

subtract(Scalar(255, 255, 255), src, dst7_2);

(3)取反操作
使用位运算中的取反操作。一般来说,位运算的速度比较快。

Mat dst7_3 = ~src;



四.图像镜像

(1)垂直镜像

(2)水平镜像

//图像镜像:水平镜像、垂直镜像
Mat dst10, dst11;    //垂直、水平
dst10.create(src.size(), src.type());
dst11.create(src.size(), src.type());
for (int row = 0; row < src.rows; row++)
{
	for (int col = 0; col < src.cols; col++)
	{
		dst10.at(row, col) = src.at(src.rows - row - 1, col);    //垂直
		dst11.at(row, col) = src.at(row, src.cols-col-1);      //水平
	}
}

五.图像旋转

原理图:


//图像旋转
Mat dst12, dst13, dst14;       //顺时针90,逆时针90,180
dst12.create(src.cols, src.rows, src.type());
dst13.create(src.cols, src.rows, src.type());
dst14.create(src.size(), src.type());
for (int row = 0; row(src.cols-col-1,src.rows-row-1) = src.at(row,col);    //顺时针90
		dst13.at(src.cols - col - 1, row) = src.at(row, col);    //逆时针90
		dst14.at(src.rows - row - 1,src.cols - col - 1) = src.at(row, col);    //180度旋转
	}
}


六.获取图像部分内容
Mat dst15,dst16;
dst16.create(src.rows / 2, src.cols / 2, src.type());
//调用函数方法
Rect rect(0, src.rows / 2, src.cols, src.rows / 2);    //左上角坐标,长,宽
dst15 = src(rect);     //截取部分图像输出
//使用像素矩阵
for (int row = 0; row < src.rows/2; row++)
{
	for (int col = 0; col < src.cols/2; col++)
	{
		dst16.at(row,col) = src.at(row, col);
	}
}

Rect类中,成员变量x、y、width、height,分别为左上角点坐标和矩形的宽和高。

七.图像信息隐藏和恢复

(1)原理
我们将图片A隐藏到图片B中,我们称图片A为被隐藏图,图片B为隐藏图。
通常情况下,图片的每个像素点占8bits,由于位数越高所占权重越大,故高位保存了图像更多的信息。
我们可以将图B的高四位保存,低四位换为图A的高四位,来隐藏图像A,这样的方法也减少了图像A的信息缺损;
恢复图像A只需将处理后的图B的低四位取出,置为高四位即可,低四位可设置为0000。
(2)代码

//信息隐藏
Mat src0 = imread("gou.jpeg");     //隐藏的图片,被隐藏的为dog(src),即把src隐藏到src0中
int tmp0,tmp1,tmp2;
for (int row = 0; row < src.rows; row++)
{
	for (int col = 0; col < src.cols; col++)
	{
		//清空低四位
		tmp0 = src0.at(row, col)[0] - src0.at(row, col)[0] % 16;
		tmp1 = src0.at(row, col)[1] - src0.at(row, col)[1] % 16;
		tmp2 = src0.at(row, col)[2] - src0.at(row, col)[2] % 16;
		//将高四位赋给低四位
		src0.at(row, col)[0] = tmp0 + src.at(row, col)[0] / 16;
		src0.at(row, col)[1] = tmp1 + src.at(row, col)[1] / 16;
		src0.at(row, col)[2] = tmp2 + src.at(row, col)[2] / 16;
	}
} 

//图像恢复
Mat dst17;
dst17.create(src.size(),src.type());
for (int row = 0; row < src.rows; row++)
{
	for (int col = 0; col < src.cols; col++)
	{
		//左移四位
		dst17.at(row, col)[0] = src0.at(row, col)[0] << 4;
		dst17.at(row, col)[1] = src0.at(row, col)[1] << 4;
		dst17.at(row, col)[2] = src0.at(row, col)[2] << 4;
	}
}


八.完整代码
#include
#include
#include
#include //高层GUI图形用户界面,包含媒体的输入输出、视频捕捉、图像和视频编码解码、图形交互界面的接口内容
#include//图像处理头文件
#include 
using namespace cv;
using namespace std;

int main()
{
	Mat src = imread("dog.jpeg");
	Mat src1 = imread("gou.jpeg");
	//调用函数生成灰度图
	Mat dst0;
	cvtColor(src, dst0, CV_BGR2GRAY);

	//编写代码生成灰度图
	Mat dst1, dst2, dst3,dst4,dst5;   //灰度图像
	Mat dst6;    //二值图像
	dst1.create(src.size(), src.type());
	dst2.create(src.size(), src.type());
	dst3.create(src.size(), src.type());
	dst4.create(src.size(), src.type());
	dst5.create(src.size(), src.type());
	dst6.create(src.size(), src.type());
	for (int row = 0; row < src.rows; row++)
	{
		for (int col = 0; col < src.cols; col++)
		{
			int b = src.at(row, col)[0];  //b通道
			int g = src.at(row, col)[1];  //g通道
			int r = src.at(row, col)[2];  //r通道
			//最大亮度转换:取rgb最大值的方法生成灰度图
			dst1.at(row, col)[0] = max(r, max(g, b));
			dst1.at(row, col)[1] = max(r, max(g, b));
			dst1.at(row, col)[2] = max(r, max(g, b));
			//最小亮度转换:取rgb最小值的方法生成灰度图
			dst2.at(row, col)[0] = min(r, min(g, b));
			dst2.at(row, col)[1] = min(r, min(g, b));
			dst2.at(row, col)[2] = min(r, min(g, b));
			//平均亮度转换:取rgb平均值的方法生成灰度图
			dst3.at(row, col)[0] = (r + g + b) / 3;
			dst3.at(row, col)[1] = (r + g + b) / 3;
			dst3.at(row, col)[2] = (r + g + b) / 3;
			//亮度优先转换
			dst4.at(row, col)[0] = (max(r, max(g, b)) + min(r, min(g, b))) / 2;
			dst4.at(row, col)[1] = (max(r, max(g, b)) + min(r, min(g, b))) / 2;
			dst4.at(row, col)[2] = (max(r, max(g, b)) + min(r, min(g, b))) / 2;
			//权重亮度转换
			dst5.at(row, col)[0] = 0.21 * r + 0.72 * g + 0.07 * b;
			dst5.at(row, col)[1] = 0.21 * r + 0.72 * g + 0.07 * b;
			dst5.at(row, col)[2] = 0.21 * r + 0.72 * g + 0.07 * b;

			//灰度图变为二值图像,采用平均亮度转换的灰度图像,阈值设为128
			if (dst3.at(row, col)[0] <= 128)
			{
				dst6.at(row, col)[0] = 0;
				dst6.at(row, col)[1] = 0;
				dst6.at(row, col)[2] = 0;
			}
			else
			{
				dst6.at(row, col)[0] = 255;
				dst6.at(row, col)[1] = 255;
				dst6.at(row, col)[2] = 255;
			}
		
		}
	}
	//图像取反,这里选择src,dst3和dst6作为原图
	Mat dst7, dst8,dst9;     //图像取反
	dst7.create(src.size(), src.type());
	dst8.create(dst3.size(), dst3.type());
	dst9.create(dst6.size(), dst6.type());
	for (int row = 0; row < src.rows; row++)
	{
		for (int col = 0; col < src.cols; col++)
		{
			//彩色图片
			int b = src.at(row, col)[0];  //b通道
			int g = src.at(row, col)[1];  //g通道
			int r = src.at(row, col)[2];  //r通道

			dst7.at(row, col)[0] = 255-b;
			dst7.at(row, col)[1] = 255-g;
			dst7.at(row, col)[2] = 255-r;
		}
	}
	//也可对图像整体做减法
	Mat dst7_1 = Scalar(255, 255, 255) - src;
	//也可以使用subtract
	Mat dst7_2;
	subtract(Scalar(255, 255, 255), src, dst7_2);
	//也可使用位运算中的取反操作。一般来说,位运算的速度比较快。
	Mat dst7_3 = ~src;

	for (int row = 0; row < dst3.rows; row++)
	{
		for (int col = 0; col < dst3.cols; col++)
		{
			//灰度图片
			int b0 = dst3.at(row, col)[0];  //b通道
			int g0 = dst3.at(row, col)[1];  //g通道
			int r0 = dst3.at(row, col)[2];  //r通道

			dst8.at(row, col)[0] = 255 - b0;
			dst8.at(row, col)[1] = 255 - g0;
			dst8.at(row, col)[2] = 255 - r0;


		}
	}

	for (int row = 0; row < dst6.rows; row++)
	{
		for (int col = 0; col < dst6.cols; col++)
		{
			//二值图片
			int b1 = dst6.at(row, col)[0];  //b通道
			int g1 = dst6.at(row, col)[1];  //g通道
			int r1 = dst6.at(row, col)[2];  //r通道

			dst9.at(row, col)[0] = 255 - b1;
			dst9.at(row, col)[1] = 255 - g1;
			dst9.at(row, col)[2] = 255 - r1;


		}
	}

	//图像镜像:水平镜像、垂直镜像
	Mat dst10, dst11;    //垂直、水平
	dst10.create(src.size(), src.type());
	dst11.create(src.size(), src.type());
	for (int row = 0; row < src.rows; row++)
	{
		for (int col = 0; col < src.cols; col++)
		{
			dst10.at(row, col) = src.at(src.rows - row - 1, col);    //垂直
			dst11.at(row, col) = src.at(row, src.cols-col-1);      //水平
		}
	}

	//图像旋转
	Mat dst12, dst13, dst14;       //顺时针90,逆时针90,180
	dst12.create(src.cols, src.rows, src.type());
	dst13.create(src.cols, src.rows, src.type());
	dst14.create(src.size(), src.type());

	for (int row = 0; row(src.cols-col-1,src.rows-row-1) = src.at(row,col);    //顺时针90
			dst13.at(src.cols - col - 1, row) = src.at(row, col);    //逆时针90
			dst14.at(src.rows - row - 1,src.cols - col - 1) = src.at(row, col);    //180度旋转
		}
	}

	//获取图像部分内容,并保存为新图像
	Mat dst15,dst16;
	dst16.create(src.rows / 2, src.cols / 2, src.type());
	//调用函数方法
	Rect rect(0, src.rows / 2, src.cols, src.rows / 2);    //左上角坐标,长,宽
	dst15 = src(rect);     //截取部分图像输出
	//使用像素矩阵
	for (int row = 0; row < src.rows/2; row++)
	{
		for (int col = 0; col < src.cols/2; col++)
		{
			dst16.at(row,col) = src.at(row, col);
		}
	}

	//信息隐藏
	Mat src0 = imread("gou.jpeg");     //隐藏的图片,被隐藏的为dog(src),即把src隐藏到src0中
	int tmp0,tmp1,tmp2;

	for (int row = 0; row < src.rows; row++)
	{
		for (int col = 0; col < src.cols; col++)
		{
			//清空低四位
			tmp0 = src0.at(row, col)[0] - src0.at(row, col)[0] % 16;
			tmp1 = src0.at(row, col)[1] - src0.at(row, col)[1] % 16;
			tmp2 = src0.at(row, col)[2] - src0.at(row, col)[2] % 16;
			//将高四位赋给低四位
			src0.at(row, col)[0] = tmp0 + src.at(row, col)[0] / 16;
			src0.at(row, col)[1] = tmp1 + src.at(row, col)[1] / 16;
			src0.at(row, col)[2] = tmp2 + src.at(row, col)[2] / 16;
		}
	} 

	//图像恢复
	Mat dst17;
	dst17.create(src.size(),src.type());
	for (int row = 0; row < src.rows; row++)
	{
		for (int col = 0; col < src.cols; col++)
		{
			//左移四位
			dst17.at(row, col)[0] = src0.at(row, col)[0] << 4;
			dst17.at(row, col)[1] = src0.at(row, col)[1] << 4;
			dst17.at(row, col)[2] = src0.at(row, col)[2] << 4;
		}
	}
	
	imshow("原图", src);    //显示处理之前的原图像
	imshow("调用函数", dst0);
	imshow("灰度图像-最大亮度转换", dst1);
	imshow("灰度图像-最小亮度转换", dst2);
	imshow("灰度图像-平均亮度转换", dst3);
	imshow("灰度图像-亮度优先转换", dst4);
	imshow("灰度图像-权重亮度转换", dst5);
	imshow("二值图像", dst6);
	imshow("图像反转-彩色图片", dst7);
	imshow("图像反转-彩色图片1", dst7_1);
	imshow("图像反转-彩色图片2", dst7_2);
	imshow("图像反转-彩色图片3", dst7_3);
	imshow("图像反转-灰度图片", dst8);
	imshow("图像反转-二值图片", dst9);
	imshow("图像镜像-垂直镜像", dst10);
	imshow("图像镜像-水平镜像", dst11);
	imshow("图像旋转-顺时针90", dst12);
	imshow("图像旋转-逆时针90", dst13);
	imshow("图像旋转-180度", dst14);
	imshow("获取图像部分内容", dst15);
	imshow("获取图像部分内容1", dst16);
	//imshow("图像缩放", dst17);
	imshow("原图0", src1);  
	imshow("隐藏", src0);
	imshow("恢复", dst17);
	//获取图像参数
	cout << "flags:" << src.flags << endl;
	cout << "size:" << src.size << endl;
	cout << "clos:" << src.cols << endl;
	cout << "rows:" << src.rows << endl;
	cout << "dims:" << src.dims << endl;
	cout << "src_channels:" << src.channels() << endl;
	cout << "dst0_channels:" << dst0.channels() << endl;
	cout << "dst6_channels:" << dst6.channels() << endl;
	cout << "size:" << src0.size << endl;
	waitKey(0);
	return 0;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/316710.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号