Open imuncle opened 4 years ago
cmake_minimum_required (VERSION 2.8) include_directories(${OpenCV_INCLUDE_DIRS}) #OpenCV的include文件夹 set(OpenCV_DIR /usr/local/lib) #OpenCV的lib文件夹 find_package(OpenCV REQUIRED) add_executable(程序名 主函数所在cpp) target_link_libraries(程序名 ${OpenCV_LIBS})
#include <opencv2/opencv.hpp> using namespace cv; void main() { Mat src = imread("../test.jpg"); imshow("【图片显示】", src); waitKey(0); //等待任意键按下 }
Mat src = imread("../test.jpg"); // OpenCV创建形态学处理的内核:MORPH_ELLIPSE、MORPH_CROSS、MORPH_RECT Mat element = getStructuringElement(MORPH_RECT, Size(15, 15)); //创建腐蚀内核 Mat dst; erode(src, dst, element); //腐蚀 imshow("【腐蚀效果图】", dst);
Mat src = imread("../test.jpg"); Mat dst; blur(src, dst, Size(7, 7)); //均值滤波 imshow("【图像模糊】", dst);
Mat src = imread("../test.jpg"); Mat dst, edge, gray; dst.create(src.size(), src.type()); //创建一个与src同类型和大小的矩阵 cvtColor(src, gray, COLOR_BGR2GRAY); //转为灰度图 blur(gray, edge, Size(3, 3)); Canny(edge, edge, 3, 9, 3); //Canny边缘检测 imshow("【Canny边缘检测】", edge);
VideoCapture capture("../1.avi"); while(1) { Mat frame; capture>>frame; //读取当前帧 imshow("【读取视频】", frame); waitKey(30); }
VideoCapture capture(0); while(1) { Mat frame; capture>>frame; //读取当前帧 imshow("【读取视频】", frame); waitKey(30); }
// flags: WINDOW_NORMAL; WINDOW_AUTOSIZE; WINDOW_OPENGL void namedWindow(const string& winname, int flags=WINDOW_AUTOSIZE)
bool imwrite(const string& filename, InputArray img, const vector<int>& params=vector<int>()); imwrite("生成的图片.jpg", img); //img为Mat对象
创建函数原型:
// value:表示滑块的位置 // count:滑块可以达到的最大位置 // userdata:传给回调函数的数据,用来处理轨迹条时间,如果value是全局变量,则不用管userdata int createTrackbar(const string& trackname, const string& winname, int* value, int count, TrackbarCallback onchange=0, void* userdata=0);
示例:
//第一个参数是轨迹条位置,第二个参数是用户数据 void on_Trackbar(int position, void* userdata) { printf("position: %d\n", position); printf("userdata: %d\n", userdata); } int main() { createTrackbar("透明值:", "【滑动条】", 0, 100, on_Trackbar, 1); }
指定鼠标操作消息回调函数的函数:
void setMouseCallback(const string& winname, MouseCallback onMouse, void* userdata = 0)
// flags是EVENT_FLAG的组合 void on_MouseHandle(int event, int x, int y, int flags, void* param) { swith(event) { case EVENT_MOUSEMOVE: { //鼠标移动事件 }break; case EVENT_LBUTTONDOWN: { //左键按下 }break; case EVENT_LBUTTONUP: { //左键抬起 }break; default:; } } int main() { Mat src = imread("../test.jpg"); setMouseCallback("【鼠标操作】", on_MouseHandle, (void*)&src); waitKey(0); }
Mat M(2, 2, CV_8UC3, Scalar(0, 0, 255)); // CV_[位数][带符号与否][类型前缀]C[通道数]
int sz[3] = {2, 2, 2}; Mat L(3, sz, CV_8UC, Scalar::all(0));
M.create(4, 4, CV_8UC2);
注意:此创建方法不能为矩阵设置初值,只是在改变尺寸时重新为矩阵数据开辟内存而已
Mat E = Mat::eye(4, 4, CV_64F); Mat O = Mat::ones(2, 2, 2CV_32F); Mat Z = Mat::zeros(3, 3, CV_8CU1);
Mat C = (Mat_<double>(3, 3) << 0, -1, 0, -1, -5, -1, 0, -1, 0);
Point point; point.x = 10; point.y = 8; Point point = Point(10, 8);
Scalar(a, b, c); //BGR
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn = 0)
getTickCount()
getTickFrequency()
Mat类有若干成员函数可以获取图像的属性。工友成员变量cols和rows给出了图像的宽和高,channels()返回图像的通道数
// 定义一个Mat类型并给其设定ROI区域 Mat imageROI; imageROI = image(Rect(500, 250, logo.cols, logo.rows)); addWeighted(srcImage1, alphaValue, srcImage2, betaValue, 0.0, dstImage);
void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype = -1) // dst = src1[I]*alpha + src2[I]*beta + gamma
Mat src = imread("../test.jpg"); vector<Mat> channels; split(src, channels); // 可以通过channels.at()访问各个通道
void merge(const Mat* mv, size_t count, OutputArray dst); void merge(const vector<Mat>& mv, OutputArray dst );
// dst需要有和src一样的尺寸和类型 void blur(InputArray src, OutputArray dst, Size ksize, Point anchor=Point(-1, -1), int borderType = BORDER_DEFAULT)
blur(image, out, Size(7, 7));
// dst需要有和src一样的尺寸和类型 // sigmaY=0时,就将它设为sigmaX void GuassianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, int borderType = BORDER_DEFAULT)
GaussianBlur(image, out, Size(3, 3), 0, 0);
// dst需要有和src一样的尺寸和类型 // ksize必须是大于1的奇数 void medianBlur(InputArray src, OutputArray dst, int ksize)
// dst需要有和src一样的尺寸和类型 // d是过滤过程中每个像素领域的直径 // sigmaColor是颜色空间滤波器的sigma值 // sigmaSpace是坐标空间滤波器的sigma值 void bilateralFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType = BORDER_DEFAULT)
bilateralFilter(image, out, 25, 25*2, 25/2);
void morphologyEx( InputArray src, OutputArray dst, int op, InputArray kernel, Point anchor = Point(-1, -1), int iterations = 1, int borderType = BORDER_CONSTANT, const Scalar& borderValue = morphologyDefaultBorderValue() );
void dilate( InputArray src, OutputArray dst, InputArray kernel, //内核,一般用getStructuringElement获取 Point anchor = Point(-1, -1); int iterations = 1, //迭代次数 int borderType = BORDER_CONSTANT, const Scalar& borderValue = morphologyDefaultBorderValue() );
Mat image = imread("../test.jpg"); Mat element = getStructuringElement(MORPH_RECT, Size(15, 15)); Mat out; dilate(image, out, element);
void erode( InputArray src, OutputArray dst, InputArray kernel, //内核,一般用getStructuringElement获取 Point anchor = Point(-1, -1); int iterations = 1, //迭代次数 int borderType = BORDER_CONSTANT, const Scalar& borderValue = morphologyDefaultBorderValue() );
Mat image = imread("../test.jpg"); Mat element = getStructuringElement(MORPH_RECT, Size(15, 15)); Mat out; erode(image, out, element);
先腐蚀后膨胀
morphologyEx(src, dst, MORPH_OPEN, element);
先膨胀后腐蚀
morphologyEx(src, dst, MORPH_CLOSE, element);
膨胀图与腐蚀图之差
morphologyEx(src, dst, MORPH_GRADIENT, element);
原图像与开运算结果图之差
morphologyEx(src, dst, MORPH_TOPHAT, element);
闭运算结果图与原图像之差
morphologyEx(src, dst, MORPH_BLACKHAT, element);
//若dsize为0,则由fx和fy计算 //若fx, fy为0,则由dsizez计算 void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR)
Threshold()对单通道数组应用固定阈值操作。
Threshold()
double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type)
threshold(gray_image, dst, thresholdValue, 255, THRESH_BINARY)
void adaptiveThreshold(InputArray src, OutputArray dst, double maxValue, int adaptiveMethod, int thresholdType, int blockSize, double C)
第一步:滤波
边缘检测的算法主要是基于图像强度的一阶和二阶导数,但导数通常对噪声很敏感,常用高斯滤波
第二步:增强
增强算法可以将图像灰度点领域强度值有显著变化的点凸显出来。在具体编程实现时,可通过计算梯度幅值来确定
第三步:检测
常用阈值化方法来检测
void Canny(InputArray image, OutputArray edges, double threshold1, double threshold2, int apertureSize = 3, bool L2gradient = false)
void Sobel( InputArray src, OutputArray dst, int ddepth, //输出图像的深度 int dx, //x方向上的差分阶数 int dy, //y方向上的差分阶数 int ksize = 3, //Sobel核的大小,必须取1/3/5/7 double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT );
void Laplacian( InputArray src, OutputArray dst, int ddepth, int ksize = 1, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT );
void HoughLines( InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn=0, double stn=0 );
在二值图像中寻找轮廓
void findContours( InputArray image, //图像需为8位单通道图像 OutputArrayOfArrays contours, OutputArray hierarchy, int mode, //RETR_EXTERNAL只检测最外层轮廓;RETR_LIST提取所有轮廓,不建立等级关系;RETR_CCOMP提取所有轮廓,组织为双层结构;RETR_TREE提取所有轮廓,建立网状的轮廓结构 int method, //轮廓的近似方法:CHAIN_APPROX_NONE获取每个轮廓的每个像素;CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标 Point offset = Point() );
常与drawContours配合使用
void drawContours( InputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar& color, int thickness = 1, int lineType = 8, InputArrayhierarchy = noArray(), int maxLevel = INT_MAX, Point offset = Point() );
vector<vector<Point>> contours; vector<Vec4i> hierarchy; findContours(src, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE); int index = 0; for(;index >= 0; index = hierarchy[index][0]) { Scalar color(rand()&255, rand()&255, rand()&255); drawContours(dst, contours, index, color, FILLED, 8, hierarchy); }
CMakeLists配置
显示图像
图像腐蚀
图像模糊
canny边缘检测
视频操作
创建窗口
保存图像
滑动条的创建和使用
创建函数原型:
示例:
鼠标操作
指定鼠标操作消息回调函数的函数:
示例:
创建Mat对象的方法
使用Mat()构造函数
通过构造函数进行初始化
利用creat()函数
采用MATLAB式的初始化方式
逗号分隔式初始化函数
常用数据结构和函数
Point类
Scalar类
cvtColor()函数
计时函数
getTickCount()
函数返回CPU自某个事件以来走过的时钟周期数getTickFrequency()
函数返回CPU一秒钟所在的时钟周期数Mat类
Mat类有若干成员函数可以获取图像的属性。工友成员变量cols和rows给出了图像的宽和高,channels()返回图像的通道数
图像混合
颜色通道分离、混合
split()函数
merge()
线性滤波
均值滤波
高斯滤波
非线性滤波
中值滤波
双边滤波
形态学滤波
核心API函数:morphologyEx()
膨胀
腐蚀
开运算
先腐蚀后膨胀
闭运算
先膨胀后腐蚀
形态学梯度
膨胀图与腐蚀图之差
顶帽
原图像与开运算结果图之差
黑帽
闭运算结果图与原图像之差
图像尺寸调整
阈值化
固定阈值操作
Threshold()
对单通道数组应用固定阈值操作。自适应阈值操作
边缘检测
第一步:滤波
边缘检测的算法主要是基于图像强度的一阶和二阶导数,但导数通常对噪声很敏感,常用高斯滤波
第二步:增强
增强算法可以将图像灰度点领域强度值有显著变化的点凸显出来。在具体编程实现时,可通过计算梯度幅值来确定
第三步:检测
常用阈值化方法来检测
canny算子
sobel算子
Laplacian算子
霍夫变换
寻找轮廓findContours()函数
在二值图像中寻找轮廓
常与drawContours配合使用
示例: