OpenCV是一个强大的图像处理库,接下来尝试进行最基本的图像打开操作。
打开图像后对图像的像素进行操作,改变图像像素的值,验证下操作是否正确。
1、打开图像
imread
函数原型:CV_EXPORTS_W Mat imread( const String& filename, int flags = IMREAD_COLOR );
返回类型:Mat
输入参数:const String& filename 文件的名称
int flags 打开文件的方式,整型可选,表示打开的色彩模式
例子:
char * szFile = "apple.jpg"; /* 图像文件的名称 */
// 读取图像文件
Mat imgOrigin = imread(szFile, IMREAD_ANYCOLOR); // 以图象的存储格式打开
2、创建OpenCV窗口
CV_EXPORTS_W void namedWindow(const String& winname, int flags = WINDOW_AUTOSIZE);
返回类型:void
参数类型:const String& winname 窗口的名称
int flags 窗口大小的方式,整型可选
例子:
namedWindow("原图", CV_WINDOW_NORMAL);
3、显示图片
函数原型:CV_EXPORTS_W void imshow(const String& winname, InputArray mat);
返回类型:void
参数类型:const String& winname 窗口的名称
InputArray mat 需要显示的mat实例
例子:
imshow("负片", desIMG);
4、获取图像中某个像素的色彩的值
Scalar color=srcImg.at
i,j 为像素的坐标,原点为视图左上角
k 为通道号,0,1,2分别对应B、G、R三个通道的颜色值
Vec3b是OpenCV以3个字节表示的三个通道颜色值的数据类型
5、代码
#include "stdafx.h"
#include
using namespace cv;
#include
using namespace std;
char * szFile = "apple.jpg"; /* 图像文件的名称 */
// 图像像素颜色值访问的at方法,图像变换为负片效果
void negativeIMG(Mat& srcImg, Mat& destImg){
/* srcImg.at(i, j)[k]
i,j 为像素的坐标,原点为视图左上角
k 为通道号,0,1,2分别对应B、G、R三个通道的颜色值 */
for (int i = 0; i(i, j)[0] = 255 - srcImg.at(i, j)[0];
destImg.at(i, j)[1] = 255 - srcImg.at(i, j)[1];
destImg.at(i, j)[2] = 255 - srcImg.at(i, j)[2];
}}
}
// 主程序
int main(int argc, char* argv[])
{
// 读取图像文件
Mat imgOrigin = imread(szFile, IMREAD_ANYCOLOR);
if (!imgOrigin.data)
return -1;
// 显示图像信息
cout << "File Name:" << szFile << endl;
cout << "Image cols:" << imgOrigin.cols << " rows:" << imgOrigin.rows << endl;
cout << "Channels of img:" << imgOrigin.channels() << endl;
cout << "Size of img:" << imgOrigin.size() << endl;
namedWindow("原图", CV_WINDOW_NORMAL);
resizeWindow("原图", imgOrigin.cols , imgOrigin.rows ); // 缩小为实际尺寸的1/4
imshow("原图", imgOrigin); // 显示图像
// 创建两个与原图像等尺寸的空的副本,作为函数执行效果的输出图
Mat desIMG,drawIMG;
desIMG.create(imgOrigin.size(), imgOrigin.type());
drawIMG.create(imgOrigin.size(), imgOrigin.type());
// 转换为负片效果进行显示
negativeIMG(imgOrigin,desIMG);
namedWindow("负片", CV_WINDOW_NORMAL);
resizeWindow("负片", desIMG.cols, desIMG.rows);
imshow("负片", desIMG);
// 隔行复制图像到绘图副本
for (int mCol = 0; mCol < imgOrigin.cols; mCol ++){
for (int mRow = 0; mRow < imgOrigin.rows; mRow+=2){
drawIMG.at(mRow, mCol) = imgOrigin.at(mRow, mCol);
/* 也可以使用下面的方式复制 */
//drawIMG.at(mRow, mCol)[0] = imgOrigin.at(mRow, mCol)[0];
//drawIMG.at(mRow, mCol)[1] = imgOrigin.at(mRow, mCol)[1];
//drawIMG.at(mRow, mCol)[2] = imgOrigin.at(mRow, mCol)[2];
}}
// 画图使用线条的宽度
int thickness = 1;
// 画图使用的线型
int lineType = 8;
// 定义一个颜色,cvScalar的储存顺序是B-G-R,而CV_RGB是R-G-B
Scalar color = CV_RGB(255, 0, 0);
//在图像中画出实心圆
circle(drawIMG, Point(drawIMG.cols / 2, drawIMG.rows / 2),
drawIMG.rows / 2, cv::Scalar(0, 255, 255), thickness);
//在图像中画空心圆
circle(drawIMG, Point(drawIMG.cols / 2, drawIMG.rows / 2),
drawIMG.rows / 4, color, thickness);
// 在图像中画出椭圆
double angle = 30; //椭圆旋转角度
//Size中的两个参数为横、纵轴长度
ellipse(drawIMG,
Point(drawIMG.cols / 2, drawIMG.rows / 2),
Size(180, 100), angle, 0, 360,
Scalar(255, 255, 0),
thickness, lineType);
// 画矩形框
Rect r(250, 250, 120, 200);
rectangle(drawIMG, r, Scalar(255, 0, 127), 2);
// 显示到窗口
namedWindow("计算图", CV_WINDOW_NORMAL);
resizeWindow("计算图", drawIMG.cols, drawIMG.rows);
imshow("计算图", drawIMG);
/* OpenCV函数,等待键盘输入, 退出*/
waitKey(0);
destroyAllWindows();
return 0;
}
原图
逐像素进行负片效果处理(用255-通道当前颜色值)
在原图副本上画图(副本像素隔行拷贝)