- 一.图像的读写
- 1.读取图像
- 2.显示图像
- 二.图像格式转换
- 1.彩色图像转为灰度图像
- 2.灰度图像转为二值图像
- 三.图像取反
- 四.图像镜像
- 五.图像旋转
- 六.获取图像部分内容
- 七.图像信息隐藏和恢复
- 八.完整代码
Mat src = imread("image_path");
注意:路径应使用 \
例如:C:\images\****.jpg
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;
通过设置阈值来指定不同范围内像素的值为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; }



