opencv 版本2.8.4
1 imread函数
Mat imread (const string& filename, int flags = 1);
Mat imread (const string& filename, int flags = 1);
1 filename:要载入的图片路径名
2 fiags为载入标识,指定一个加载图像的颜色类型,默认值为1,表示载入三通道的彩色图像。这个参数可以在OpenCV中标识图像格式的枚举体中取值。若为0,灰度图像。若为2:当载入图像的深度为16位或者32位,返回对应深度的图像,否则转换为8位图像再返回。
3因为flags是int类型得到变量,若不在枚举体里取固定的值,可以这样进行:
- flags>0 返回一个3通道彩色图像
- flags=0返回灰度图像
- flags<0返回包含Alpha通道的加载图像
4 注意:若以彩色模式载入图像,解码后的图像会以BGR的通道进行存储,即蓝,绿,红的顺序,不是通常的RGB顺序。
Mat image0 = imread("1.jpg", 2|4) ;//载入无损的原图像
Mat image1 = imread("1.jpg", 0);//载入灰度图
Mat image2 = imread("1.jpg", 199);//载入3通道的彩色图像
2 imshow函数
void imshow (const string& winname, InputArray mat);
void imshow (const string& winname, InputArray mat);
1 winname:填需要显示的窗口标识名称。
2 mat:需要显示的图像
- 如果载入图像是8位无符号类型,就显示图像本来的样子
- 如果图像是16位无符号类型或32位整型,用像素值除以256,值的范围是[0, 256x256]映射到[0, 255]
- 如果图像是32位浮点型,像素值要乘以255.该值的范围是[0, 1]映射到[0, 255]。
3 namedWindow()函数
void namedWindow(const string& winname, int flags = WINDOW_AUTOSIZE);
void namedWindow(const string& winname, int flags = WINDOW_AUTOSIZE);
1 name:窗口名字
2 flags:窗口标识
- WINDOW_NORMAL——用户可以改变窗口大小(没有限制)CV_WINDOW_NORMAL
- WINDOW_AUTOSIZE——窗口大小自适应,用户不能改变CV_WINDOW_AUTOSIZE
- WIDNOW_OPENGL——窗口支持OPENGL CV_WINDOW_OPENGL
3 可以用destroyWindow()函数来关闭窗口,不常用
4. imwrite()函数
bool imwrite(const string& filename, InputArray img, const vector<int>& params = vector<int>());
1 filename:要写入的文件名
2 img:填一个mat类型的图像数据
3 params,表示为特定格式保存的编码,一般情况下,不需要填写。
- 对于JPEG格式的图片,这个参数表示从0到100的图片质量(CV_IMWRITE_JPEG_QUALITY)默认值是95
- 对于png格式,这个参数表示压缩级别(CV_IMWRITE_PNG_COMPRESSION)从0到9,较高值以为值更小的尺寸和更长的压缩时间,默认值3
- 对于ppm,pgm,或pbm格式的图片,这个参数表示一个二进制格式标志(CV_IMWRITE_PXM_BINARY)取值为0或1, 默认值是1
5. 滑动条的创建和使用
1 createTrackbar()函数
int createTrackbar(const string& trackbarname, const string& winname, int *value, int count, TrackbarCallback onChange = 0, void* userdata = 0);
- trackbarname:轨迹条的名字
- winname:窗口的名字,表示这个轨迹条会依附到那个窗口上、
- value:指向int的指针,表示滑块的位置,滑块的初试位置就是该变量当前的值。
- count:表示滑块可以达到的最大位置的值。滑块最小位置始终为0
- trackbarcallback类型的onchange,它有默认值为0.这是一个指向回调函数的指针,每次滑块位置改变时,这个函数都会进行回调。并且这个函数的原型必须为void xxxx(int, void*) 其中,第一个参数是轨迹条的位置,第二个参数是用户数据,如果回调是null指针,则表示没有回调函数的调用,仅第三个参数value有变化。
- userdata也有默认值0, 这个从参数是用户传给回调函数的数据,用来处理轨迹条事件。如果使用的第三个参数value实参是全局变量的话,可以不用管这个参数。
2 getTrackbarPos()函数--用于获取当前轨迹条的位置
int getTrackbarPos(const string& trackbarname, const string& winname);
int getTrackbarPos(const string& trackbarname, const string& winname);
- trackbarname:轨迹条的名字
- winname:轨迹条父窗口的名称
6 鼠标操作
SetMouseCallback函数的作用是为指定的窗口设置鼠标回调函数,原型如下:
void setMouseCallback(const string& winname, MouseCallback onMouse, void* userdata = 0);
void setMouseCallback(const string& winname, MouseCallback onMouse, void* userdata = 0);
1 winname:窗口名字
2 onMouse:指定窗口里每次鼠标事件发生的时候,被调用的函数指针。这个函数的原型的大概形式为
void Foo(int event, int x, int y, int flags, void *param)
其中event是EVENT_+变量之一,x和y是鼠标指针在图像坐标系(不是窗口坐标系)中的坐标值,flags是EVENT_FLAG的组合,param是用户定义的传递到setmousecallback函数调用的参数。如EVENT_MOUSEMOVE为鼠标移动消息、EVENT_LBUTTONDOWN为鼠标左键按下消息。
3 userdata:有默认值0.
代码示例
1 图像腐蚀
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc//imgproc.hpp>
using namespace cv;
int main_2()
{
Mat srcImage = imread("pic.jpg");
imshow("[原图]腐蚀操作", srcImage);
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
Mat dstImage;
erode(srcImage, dstImage, element);
imshow("[效果图]腐蚀操作", dstImage);
waitKey(0);
return 0;
}
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc//imgproc.hpp>
using namespace cv;
int main_2()
{
Mat srcImage = imread("pic.jpg");
imshow("[原图]腐蚀操作", srcImage);
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
Mat dstImage;
erode(srcImage, dstImage, element);
imshow("[效果图]腐蚀操作", dstImage);
waitKey(0);
return 0;
}
2 模糊
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
int main_3()
{
Mat srcImage = imread("pic.jpg");
imshow("均值滤波【原图】", srcImage);
Mat dstImage;
blur(srcImage, dstImage, Size(7, 7));
imshow("均值滤波【效果图】", dstImage);
waitKey(0);
return 0;
}
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
int main_3()
{
Mat srcImage = imread("pic.jpg");
imshow("均值滤波【原图】", srcImage);
Mat dstImage;
blur(srcImage, dstImage, Size(7, 7));
imshow("均值滤波【效果图】", dstImage);
waitKey(0);
return 0;
}
3 边缘检测
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
int main_4()
{
Mat srcImage = imread("pic.jpg");
imshow("【原始图】Canny边缘检测", srcImage);
Mat dstImage, edge, grayImage;
dstImage.create(srcImage.size(), srcImage.type());//创建与src同类型和大小的矩阵
//将原图像转换为灰度图像
cvtColor(srcImage, grayImage, CV_BGR2GRAY);//opecv2 代码版本
blur(grayImage, edge, Size(3, 3));
Canny(edge, edge, 3, 9, 3);
imshow("【效果图】Canny边缘检测", edge);
waitKey(0);
return 0;
}
//不知道这里的dstImage是干什么的
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
int main_4()
{
Mat srcImage = imread("pic.jpg");
imshow("【原始图】Canny边缘检测", srcImage);
Mat dstImage, edge, grayImage;
dstImage.create(srcImage.size(), srcImage.type());//创建与src同类型和大小的矩阵
//将原图像转换为灰度图像
cvtColor(srcImage, grayImage, CV_BGR2GRAY);//opecv2 代码版本
blur(grayImage, edge, Size(3, 3));
Canny(edge, edge, 3, 9, 3);
imshow("【效果图】Canny边缘检测", edge);
waitKey(0);
return 0;
}
//不知道这里的dstImage是干什么的
4 使用摄像头
#include <opencv2/opencv.hpp>
using namespace cv;
// int main()
// {
// //VideoCapture capture("1.avi");//读取视频
// VideoCapture capture(0);//调取摄像头
// while(1)
// {
// Mat frame;
// capture >> frame;
// imshow("读取视频", frame);
// waitKey(1);
// }
// return 0;
// }
int main_5()
{
VideoCapture capture(0);
Mat edges;
while(1)
{
Mat frame;
capture >> frame;
cvtColor(frame, edges, CV_BGR2GRAY);
blur(edges, edges,Size(7, 7));
Canny(edges, edges, 0, 30, 3);
imshow("Canny后的视频", edges);
if (waitKey(30) >= 0)
{
break;
}
}
return 0;
}
#include <opencv2/opencv.hpp>
using namespace cv;
// int main()
// {
// //VideoCapture capture("1.avi");//读取视频
// VideoCapture capture(0);//调取摄像头
// while(1)
// {
// Mat frame;
// capture >> frame;
// imshow("读取视频", frame);
// waitKey(1);
// }
// return 0;
// }
int main_5()
{
VideoCapture capture(0);
Mat edges;
while(1)
{
Mat frame;
capture >> frame;
cvtColor(frame, edges, CV_BGR2GRAY);
blur(edges, edges,Size(7, 7));
Canny(edges, edges, 0, 30, 3);
imshow("Canny后的视频", edges);
if (waitKey(30) >= 0)
{
break;
}
}
return 0;
}
5 imwrite使用
#include <opencv2/opencv.hpp>
#include <stdio.h>
#include <vector>
using namespace std;
using namespace cv;
void creatAlphaMat(Mat &mat)
{
for (int i = 0; i < mat.rows; ++i)
{
for (int j = 0; j < mat.cols; ++j)
{
Vec4b &rgba = mat.at<Vec4b>(i, j);
rgba[0] = UCHAR_MAX;
rgba[1] = saturate_cast<uchar>((float(mat.cols - j)) / ((float)mat.cols) * UCHAR_MAX);
rgba[2] = saturate_cast<uchar>((float(mat.rows - i)) / ((float)mat.rows) * UCHAR_MAX);
rgba[3] = saturate_cast<uchar>(0.5 * (rgba[1] + rgba[2]));
}
}
}
int main_6()
{
Mat mat(480, 640, CV_8UC4);
creatAlphaMat(mat);//创建带Alpha通道的mat
vector<int>compression_params;
//compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);//书中写这句是v2的下面两句是v3的,但是这里库是v248的,要是用下面的代码才能运行成功
compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
compression_params.push_back(9);
try
{
imwrite("透明Alpha值图.png", mat, compression_params);
imshow("生成的png图", mat);
fprintf(stdout, "png图片文件的alpha数据保存完毕~\n 可以在工程目录下查看由imwrite函数生成的图片\n");
waitKey(0);
}
catch(runtime_error& ex)
{
fprintf(stderr, "图像转换成png格式发生错误:%s\n", ex.what());
return 1;
}
return 0;
}
#include <opencv2/opencv.hpp>
#include <stdio.h>
#include <vector>
using namespace std;
using namespace cv;
void creatAlphaMat(Mat &mat)
{
for (int i = 0; i < mat.rows; ++i)
{
for (int j = 0; j < mat.cols; ++j)
{
Vec4b &rgba = mat.at<Vec4b>(i, j);
rgba[0] = UCHAR_MAX;
rgba[1] = saturate_cast<uchar>((float(mat.cols - j)) / ((float)mat.cols) * UCHAR_MAX);
rgba[2] = saturate_cast<uchar>((float(mat.rows - i)) / ((float)mat.rows) * UCHAR_MAX);
rgba[3] = saturate_cast<uchar>(0.5 * (rgba[1] + rgba[2]));
}
}
}
int main_6()
{
Mat mat(480, 640, CV_8UC4);
creatAlphaMat(mat);//创建带Alpha通道的mat
vector<int>compression_params;
//compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);//书中写这句是v2的下面两句是v3的,但是这里库是v248的,要是用下面的代码才能运行成功
compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
compression_params.push_back(9);
try
{
imwrite("透明Alpha值图.png", mat, compression_params);
imshow("生成的png图", mat);
fprintf(stdout, "png图片文件的alpha数据保存完毕~\n 可以在工程目录下查看由imwrite函数生成的图片\n");
waitKey(0);
}
catch(runtime_error& ex)
{
fprintf(stderr, "图像转换成png格式发生错误:%s\n", ex.what());
return 1;
}
return 0;
}
6 混合
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
int main_7()
{
Mat girl = imread("girl.jpg");
namedWindow("[1]动漫图");
imshow("[1]动漫图", girl);
Mat image = imread("dota.jpg", 199);
Mat logo = imread("dota_logo.jpg");
namedWindow("[2]原画图");
imshow("[2]原画图", image);
namedWindow("[3]logo图");
imshow("[3]logo图", logo);
Mat imageROI;
imageROI = image(Rect(800, 350, logo.cols, logo.rows));
addWeighted(imageROI, 0.5, logo, 0.3, 0., imageROI);
namedWindow("[4]原画+logo图");
imshow("[4]原画+logo图", image);
imwrite("由imwrite生成的图片.jpg", image);
waitKey(0);
return 0;
}
7 进度条
#include <opencv2/opencv.hpp>
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
#define WINDOW_NAME "【线性混合示例】"
const int g_nMaxAlphaValue = 100; //alpha 的最大值
int g_nAlphaValueSlider;//滑动条对应的变量
double g_dAlphaValue;
double g_dBetaValue;
Mat g_srcImage1;
Mat g_srcImage2;
Mat g_dstImage;
void on_Trackbar(int , void*)
{
//求出当前alpha值相对于最大值的比例
g_dAlphaValue = (double) g_nAlphaValueSlider / g_nMaxAlphaValue;
//beta值为1-Alpha
g_dBetaValue = (1.0 - g_dAlphaValue);
//根据alpha和beta进行线性混合
addWeighted(g_srcImage1, g_dAlphaValue, g_srcImage2, g_dBetaValue, 0.0, g_dstImage);
imshow(WINDOW_NAME, g_dstImage);
}
int main_8()
{
g_srcImage1 = imread("1.jpg");
g_srcImage2 = imread("2.jpg");
if (!g_srcImage1.data)
{
printf("读取第一幅图片错误,请确定目录下是否有imread函数指定的图片存在~!\n");
return -1;
}
if (!g_srcImage2.data)
{
printf("读取第二幅图片错误,请确定目录下是否有imread函数指定的图片存在~!\n");
return -1;
}
g_nAlphaValueSlider = 70;//滑动条初值为70
namedWindow(WINDOW_NAME, 1);
char TrackbarName[50];
sprintf(TrackbarName, "透明值 %d", g_nMaxAlphaValue);
createTrackbar(TrackbarName, WINDOW_NAME, &g_nAlphaValueSlider, g_nMaxAlphaValue, on_Trackbar);
on_Trackbar(g_nAlphaValueSlider, 0);
waitKey(0);
return 0;
}
#include <opencv2/opencv.hpp>
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
#define WINDOW_NAME "【线性混合示例】"
const int g_nMaxAlphaValue = 100; //alpha 的最大值
int g_nAlphaValueSlider;//滑动条对应的变量
double g_dAlphaValue;
double g_dBetaValue;
Mat g_srcImage1;
Mat g_srcImage2;
Mat g_dstImage;
void on_Trackbar(int , void*)
{
//求出当前alpha值相对于最大值的比例
g_dAlphaValue = (double) g_nAlphaValueSlider / g_nMaxAlphaValue;
//beta值为1-Alpha
g_dBetaValue = (1.0 - g_dAlphaValue);
//根据alpha和beta进行线性混合
addWeighted(g_srcImage1, g_dAlphaValue, g_srcImage2, g_dBetaValue, 0.0, g_dstImage);
imshow(WINDOW_NAME, g_dstImage);
}
int main_8()
{
g_srcImage1 = imread("1.jpg");
g_srcImage2 = imread("2.jpg");
if (!g_srcImage1.data)
{
printf("读取第一幅图片错误,请确定目录下是否有imread函数指定的图片存在~!\n");
return -1;
}
if (!g_srcImage2.data)
{
printf("读取第二幅图片错误,请确定目录下是否有imread函数指定的图片存在~!\n");
return -1;
}
g_nAlphaValueSlider = 70;//滑动条初值为70
namedWindow(WINDOW_NAME, 1);
char TrackbarName[50];
sprintf(TrackbarName, "透明值 %d", g_nMaxAlphaValue);
createTrackbar(TrackbarName, WINDOW_NAME, &g_nAlphaValueSlider, g_nMaxAlphaValue, on_Trackbar);
on_Trackbar(g_nAlphaValueSlider, 0);
waitKey(0);
return 0;
}
8 鼠标操作
// StudyOpenCV_10鼠标的使用.cpp: 定义控制台应用程序的入口点。
//
//------------------Rect的知识---------------------
//Rect_类有些意思,成员变量x、y、width、height,分别为左上角点的坐标和矩形的宽和高。
//常用的成员函数有Size()返回值为一个Size,area()返回矩形的面积,contains(Point)用来判断点是否在矩形内,
//inside(Rect)函数判断矩形是否在该矩形内,tl()返回左上角点坐标,br()返回右下角点坐标
//-------------------RNG随机数产生器-------------------------
//RNG类。它可以压缩一个64位的i整数并可以得到scalar和array的随机数。
//目前的版本支持均匀分布随机数和Gaussian分布随机数。随机数的产生采用的是Multiply - With - Carry算法和Ziggurat算法。
//其构造函数的初始化可以传入一个64位的整型参数作为随机数产生器的初值。next可以取出下一个随机数,
//uniform函数可以返回指定范围的随机数,gaussian函数返回一个高斯随机数,fill则用随机数填充矩阵。
#include "stdafx.h"
#include<opencv2/opencv.hpp>
using namespace cv;
#define WINDOW_NAME "【程序窗口】"
//--------------------全局函数声明部分--------------------
void on_MouseHandle(int event, int x, int y, int flage, void *param);
void DrawRectangle( cv::Mat & img, cv::Rect box);
//--------------------全局变量声明部分--------------------
Rect g_rectangle;
bool g_bDrawingBox = false; //是否进行绘制图形
RNG g_rng(12345); //随机数产生器
int main()
{
//【1】准备参数
g_rectangle = Rect(-1, -1, 0, 0);
//一个长为600, 宽为800的窗口
//CV_8UC3 是创建----8位无符号的三通道---RGB彩色图像
Mat srcImage(600, 800, CV_8UC3);
//设置一个临时变量
Mat tempImage;
//将srcImage中的值复制给临时变量tempImage
srcImage.copyTo(tempImage);
//将srcImage中的值全部设置为0
srcImage = Scalar::all(0);
//【2】设置鼠标操作回调函数
namedWindow(WINDOW_NAME);
setMouseCallback(WINDOW_NAME, on_MouseHandle, (void*) &srcImage);
//【3】程序主循环,当进行绘制的标识符为真时,进行绘制
/*注意:不能在毁掉函数中写入未初始化的矩阵类,所以需要用时,需要写一个标志位,然后再在while(1)循环内使用*/
while (1)
{
//复制原图到临时变量
srcImage.copyTo(tempImage);
if (g_bDrawingBox)//当进行绘制的标识为真,则进行绘制
{
DrawRectangle(tempImage, g_rectangle);
}
imshow(WINDOW_NAME, tempImage);
if (waitKey(10) == 27) //按下esc键,程序退出
{
break;
}
}
return 0;
}
//--------------------【on_MouseHandle函数】--------------------
//--------------------鼠标回调函数,根据不同的鼠标事件进行不同的操作--------------------
//----参数解释:
//-------event是 CV_EVENT_*变量之一
//EVENT_MOUSEMOVE 滑动
//EVENT_LBUTTONDOWN 左击
//EVENT_RBUTTONDOWN 右击
//EVENT_MBUTTONDOWN 中键点击
//EVENT_LBUTTONUP 左键放开
//EVENT_RBUTTONUP 右键放开
//EVENT_MBUTTONUP 中键放开
//EVENT_LBUTTONDBLCLK 左键双击
//EVENT_RBUTTONDBLCLK 右键双击
//EVENT_MBUTTONDBLCLK 中键双击
//------- x和y是鼠标指针在图像坐标系的坐标(不是窗口坐标系)
//------- flags是CV_EVENT_FLAG的组合,flag的状态有:
//EVENT_FLAG_LBUTTON 左键拖拽
//EVENT_FLAG_RBUTTON 右键拖拽
//EVENT_FLAG_MBUTTON 中键拖拽
//EVENT_FLAG_CTRLKEY 按住Ctrl不放
//EVENT_FLAG_SHIFTKEY 按住Shift不放
//EVENT_FLAG_ALTKEY 按住Alt不放
//------- param是用户定义的传递到setMouseCallback函数调用的参数。
void on_MouseHandle(int event, int x, int y, int flage, void *param)
{
Mat& image = *(cv::Mat*) param;
switch (event)
{
//鼠标移动消息
case EVENT_MOUSEMOVE: {
//如果是否进行绘制的标识符为真,则记录下长和宽到RECT型变量中
if (g_bDrawingBox) {
//g_rectangle.x 是矩形 左上角的x坐标值 g_rectangle.y是矩形 左上角的y坐标值
g_rectangle.width = x - g_rectangle.x;
g_rectangle.height = y - g_rectangle.y;
}
} break;
//左键按下消息
case EVENT_LBUTTONDOWN:
{
g_bDrawingBox = true;
g_rectangle = Rect(x, y, 0, 0);//记录起始点
}break;
//左键抬起消息
case EVENT_LBUTTONUP:
{
//置标识符为false
g_bDrawingBox = false;
//对宽和高小于0的处理
//鼠标移动的方向是从右往左
if (g_rectangle.width < 0)
{
g_rectangle.x += g_rectangle.width;
g_rectangle.width *= -1;
}
//鼠标移动的方向是从下往上
if (g_rectangle.height < 0)
{
g_rectangle.y += g_rectangle.height;
g_rectangle.height *= -1;
}
//调用函数进行绘制
DrawRectangle(image, g_rectangle);
}break;
default:
break;
}
}
//--------------------【DrawRectangle()函数】--------------------
//--------------------自定义的矩形绘制函数--------------------
void DrawRectangle(cv::Mat& img, cv::Rect box)
{
//利用对角线(x,y)和( x+width, y+height )来画矩形
rectangle(img, box.tl(), box.br(), Scalar(g_rng.uniform(0,255),
g_rng.uniform(0, 255), g_rng.uniform(0, 255))); //随机颜色
}