网站推广机构,苏州有哪些it大厂,爱奇艺网站建设费,dw网站站点建立后怎么做Opencv
Opencv每一篇目具体#xff1a; Opencv(1)读取与图像操作 Opencv(2)绘图与图像操作 Opencv(3)详解霍夫变换 Opencv(4)详解轮廓 Opencv(5)平滑处理 具体Opencv相关demo代码欢迎访问我的github仓库#xff08;包含python和c代码#xff09; demo代码 文章目录 Opencv一…Opencv
Opencv每一篇目具体 Opencv(1)读取与图像操作 Opencv(2)绘图与图像操作 Opencv(3)详解霍夫变换 Opencv(4)详解轮廓 Opencv(5)平滑处理 具体Opencv相关demo代码欢迎访问我的github仓库包含python和c代码 demo代码 文章目录 Opencv一、读取图片(1).imread(2).namedWindow(3).imshow 二、像素操作(1).访问像素1. at()2.Mat_ (2).遍历像素1.指针遍历2.迭代器遍历 (3).threshold(4).通道分离1.split2.merge (5)Gamma矫正(6).深浅拷贝 三、基本绘图(1).line(2).rectangle(3).circle 四、图像处理(1).颜色空间1.意义2.cvtColor()3.inRange()4.适应光线 (2).形态操作1.腐蚀2.膨胀3.开/闭运算4.error (3).平滑处理1.均值滤波2.方框滤波3.高斯滤波4.中值滤波5.双边滤波 (4).Ganny边缘检测1.图像平滑2.图像梯度3.Ganny原理4.Canny() (5).霍夫变换1.霍夫线变换1.1 原理1.2 HoughLines() 2.霍夫圆变换2.1 原理2.2 HoughCircles() 五、轮廓(1).查找绘制1.findContours()2.drawContours() (2).层级结构(3).筛选轮廓(4).凸包 六、Functions(1).createTrackbar()(2).SetMouseCallback() 一、读取图片 (1).imread
Mat imread(const string filename, intflags1 );flags:
enum
{
/* 8bit, color or not */CV_LOAD_IMAGE_UNCHANGED -1,
/* 8bit, gray */CV_LOAD_IMAGE_GRAYSCALE 0,
/* ?, color */CV_LOAD_IMAGE_COLOR 1,
/* any depth, ? */CV_LOAD_IMAGE_ANYDEPTH 2,
/* ?, any color */CV_LOAD_IMAGE_ANYCOLOR 4
};Mat image0imread(dota.jpg,CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);//载入最真实的图像
Mat image1imread(dota.jpg,0);//载入灰度图
Mat image2imread(dota.jpg,199);//载入3通道的彩色图像
Mat logoimread(dota_logo.jpg);//载入3通道的彩色图像CV_LOAD_IMAGE_UNCHANGED这个标识在新版本中被废置了忽略。CV_LOAD_IMAGE_ANYDEPTH- 如果取这个标识的话若载入的图像的深度为16位或者32位就返回对应深度的图像否则就转换为8位图像再返回。CV_LOAD_IMAGE_COLOR- 如果取这个标识的话总是转换图像到彩色一体CV_LOAD_IMAGE_GRAYSCALE- 如果取这个标识的话始终将图像转换成灰度 flags 0返回一个3通道的彩色图像。flags 0返回灰度图像。flags 0返回包含Alpha通道的加载的图像。
(2).namedWindow
void namedWindow(const string winname,int flagsWINDOW_AUTOSIZE ); WINDOW_NORMAL设置了这个值用户便可以改变窗口的大小没有限制WINDOW_AUTOSIZE如果设置了这个值窗口大小会自动调整以适应所显示的图像并且不能手动改变窗口大小。WINDOW_OPENGL 如果设置了这个值的话窗口创建的时候便会支持OpenGL。
(3).imshow
void imshow(const string winname, InputArray mat);二、像素操作
(1).访问像素
1. at()
image.atuchar(j,i) value; //单通道
image.atcv::Vec3b(j,i)[channel] value; //三通道
image.atcv::Vec3b(j,i) cv::Vec3b(a,b,c);2.Mat_
cv::Mat_uchar image(image1);
image(20,30) value;(2).遍历像素
1.指针遍历
uchar *data image.ptruchar(i); //ptr()返回行的地址for (int i 0; i height; i) {cv::Vec3b* row image.ptrcv::Vec3b(i);for (int j 0; j width; j) {cv::Vec3b pixel row[j];//Vec3b直接操作图像中的像素值而不需要创建新的对象std::cout Pixel at ( i , j ): B (int)pixel[0] G (int)pixel[1] R (int)pixel[2] std::endl;}
}2.迭代器遍历
cv::MatIterator_ cv::Vec3b it;
或者
cv::Mat_cv::Vec3b::iterator it;cv::MatIterator_cv::Vec3b it, end;
for (it image.begincv::Vec3b(), end image.endcv::Vec3b(); it ! end; it) {cv::Vec3b pixel *it;pixel[0] 255; pixel[1] 0; pixel[2] 0;
}(3).threshold
double cv::threshold(src, OutputArray, thresh, maxval, type)(4).通道分离
1.split
C: void split(const Mat src, Mat*mvbegin);
C: void split(InputArray m,OutputArrayOfArrays mv);2.merge
C: void merge(const Mat* mv, size_tcount, OutputArray dst)
C: void merge(InputArrayOfArrays mv,OutputArray dst)(5)Gamma矫正
Gamma校正是对输入图像灰度值进行的非线性操作使输出图像灰度值与输入图像灰度值呈指数关系。Gamma矫正用于调整图像的亮度和对比度。Gamma矫正可以改变图像的灰度值分布使图像在显示时看起来更加自然和逼真。通常情况下人眼对亮度的感知是非线性的因此使用Gamma矫正可以更好地模拟人眼的感知特性。 V o u t A V i n γ V_{out}AV_{in}^\gamma VoutAVinγ γ的值决定了输入图像和输出图像之间的灰度映射方式即决定了是增强低灰度值区域还是增高灰度值区域。 γ1时图像的高灰度区域对比度得到增强直观效果是一幅偏亮的图变暗了下来。 γ1时图像的低灰度区域对比度得到增强直观效果是一幅偏暗的图变亮了起来。
(6).深浅拷贝
浅拷贝是指当图像之间进行赋值时图像数据并未发生复制而是两个对象都指向同一块内存块。
深拷贝是指新创建的图像拥有原始图像的崭新拷贝
三、基本绘图
(1).line
void cv::line(InputOutputArray img,Point pt1, Point pt2, const Scalar color, int thickness 1, int lineType LINE_8, int shift 0)imgImage.pt1First point of the line segment.pt2Second point of the line segment.colorLine color.thicknessLine thickness.lineTypeType of the line. See LineTypes.shiftNumber of fractional bits in the point coordinates.
(2).rectangle
void cv::rectangle(InputOutputArray img, Point pt1, Point pt2, const Scalar color, int thickness 1,int lineType LINE_8, int shift 0)void cv::rectangle(InputOutputArray img, Rect rec, const Scalar color, int thickness 1,int lineType LINE_8, int shift 0) (3).circle
void cv::circle(InputOutputArray img, Point center, int radius, const Scalar color, int thickness 1, int lineType LINE_8, int shift 0)thickness -1 为实心圆
四、图像处理
(1).颜色空间
1.意义 RGB 颜色空间利用三个颜色分量的线性组合来表示颜色任何颜色都与这三个分量有关而且这三个分量是高度相关的所以连续变换颜色时并不直观想对图像的颜色进行调整需要更改这三个分量才行。 自然环境下获取的图像容易受自然光照、遮挡和阴影等情况的影响即对亮度比较敏感。而 RGB 颜色空间的三个分量都与亮度密切相关即只要亮度改变三个分量都会随之相应地改变而没有一种更直观的方式来表达。 在图像处理中使用较多的是 HSV 颜色空间它比 RGB 更接近人们对彩色的感知经验。非常直观地表达颜色的色调、鲜艳程度和明暗程度方便进行颜色的对比。
H色调/hue |
S饱和度/saturation |
V明度/Value |
2.cvtColor()
void cv::cvtColor(InputArray src, OutputArray dst, int code, int dstCn0)src输入图像可以是Mat类型的图像或者其他支持的图像数据结构。dst输出图像用于存储转换后的图像。code颜色空间转换的代码例如CV_BGR2GRAY表示将BGR颜色空间转换为灰度图像。dstCn输出图像的通道数如果为0则自动根据code参数确定通道数。
3.inRange()
void inRange(InputArray src, InputArray lowerb,InputArray upperb, OutputArray dst);
void inRange(image, Scalar(hmin,smin,vmin), Scalar(hmax,smax,vmax), image);
//typedef Vecdouble, 4 Scalar;4.适应光线
光线较暗 - 暗色调 增加饱和度S 减小亮度V
光线较亮 - 亮色调 减小饱和度S 增大亮度V
(2).形态操作
1.腐蚀
腐蚀的基本概念就像土壤侵蚀一样只侵蚀前景对象的边界总是尽量保持前景为白色。那它有什么作用呢内核在图像中滑动如二维卷积。只有当内核下的所有像素都为 1 时原始图像中的像素1 或 0才会被视为 1否则会被侵蚀变为零。
C: void erode(InputArray src,OutputArray dst,InputArray kernel,Point anchorPoint(-1,-1),int iterations1,int borderTypeBORDER_CONSTANT,const Scalar borderValuemorphologyDefaultBorderValue()); int g_nStructElementSize 3; //结构元素(内核矩阵)的尺寸//获取自定义核
Mat element getStructuringElement(MORPH_RECT,Size(2*g_nStructElementSize1,2*g_nStructElementSize1),Point( g_nStructElementSize, g_nStructElementSize ));2.膨胀
它与腐蚀正好相反。这里如果内核下至少有一个像素为“1”则像素元素为“1”。所以它会增加图像中的白色区域或者增加前景对象的大小。通常情况下在去除噪音的情况下腐蚀后会膨胀。因为腐蚀消除了白噪声但它也缩小了我们的对象。所以我们扩大它。由于噪音消失了它们不会再回来但我们的目标区域会增加到腐蚀之前的状态。它还可用于连接对象的断开部分。
C: void dilate(InputArray src,OutputArray dst,InputArray kernel,Point anchorPoint(-1,-1),int iterations1,int borderTypeBORDER_CONSTANT,const Scalar borderValuemorphologyDefaultBorderValue()
);3.开/闭运算 开运算Opening Operation其实就是先腐蚀后膨胀的过程。开运算可以用来消除小物体、在纤细点处分离物体、平滑较大物体的边界的同时并不明显改变其面积。 先膨胀后腐蚀的过程称为闭运算(Closing Operation)闭运算能够排除小型黑洞(黑色区域)。
C: void morphologyEx(
InputArray src,
OutputArray dst,
int op,
InputArraykernel,
PointanchorPoint(-1,-1),
intiterations1,
intborderTypeBORDER_CONSTANT,
constScalar borderValuemorphologyDefaultBorderValue()
);第三个参数int类型的op表示形态学运算的类型可以是如下之一的标识符
MORPH_OPEN – 开运算Opening operationMORPH_CLOSE – 闭运算Closing operationMORPH_GRADIENT -形态学梯度Morphological gradientMORPH_TOPHAT - “顶帽”“Top hat”MORPH_BLACKHAT - “黑帽”“Black hat“MORPH_ERODE-“腐蚀”MORPH_DILATE-“膨胀”
4.error
problem : /…/lib/libstdc.so.6: version GLIBCXX_3.4.30’ not found
solve : 系统环境下 /usr/lib/x86_64-linux-gnu/libstdc.so.6 文件含有GLIBCXX_3.4.30版本而anaconda环境下libstdc.so.6文件含有的最高版本为GLIBCXX_3.4.29因此有了前面的报错。
rm libstdc.so
rm libstdc.so.6
ln -s /usr/lib/x86_64-linux-gnu/libstdc.so.6.0.32 libstdc.so
ln -s /usr/lib/x86_64-linux-gnu/libstdc.so.6.0.32 libstdc.so.6(3).平滑处理
图像的平滑处理是在尽量图像原有信息的情况下过滤掉图像内部的噪声。由于图像平滑处理的同时通常伴随着图像的模糊操作有时图像平滑处理也称为图像模糊处理。使用滤波器模板确定的邻域内像素的平均/加权平均灰度值代替图像中每个像素的值。平滑线处理滤波器也称均值滤波器
1.均值滤波
dst cv2.blur(src, ksize, anchor, borderType)2.方框滤波
dst cv2.boxFilter(src, ddepth, ksize, anchor, normalize, borderType)3.高斯滤波
dst cv2.GauusianBlur(src, ksize, sigmaX, sigmaY, borderType)4.中值滤波
dst cv2.medianBlur(src, ksize)5.双边滤波
边缘滤波保留是一种图像处理技术旨在在应用滤波器时保留图像中的边缘信息。在图像处理中滤波器通常用于平滑图像或者增强特定的图像特征但是滤波器也可能导致边缘信息的模糊或丢失。通过在滤波过程中保留边缘信息从而在平滑图像的同时保持图像中的边缘清晰度
dst cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace, dst, borderType)d过滤过程中每个像素邻域的直径范围。如果不是正数则函数会从参数 sigmaSpace 计算该值 sigmaColor颜色空间过滤器的 sigma 值参数的值越大表明该像素邻域内有越宽广的颜色会被混合到一起产生较大的半等色区域 sigmaSpace坐标空间中滤波器的 sigma 值如果该值较大则意味着越远的像素将相互影响从而使更大的区域中足够相似的颜色获取相同的颜色。当 d0 时d 指定了邻域大小且与 sigmaSpace 无关否则 d 正比于 sigmaSpace。
一般将 sigmaSpace设置大一些sigmaColor 设置小一些最终呈现的效果较好。ygtr21
(4).Ganny边缘检测
1.图像平滑
2.图像梯度
图像梯度可以把图像看成二维离散函数图像梯度简单来说就是求导在图像上表现出来的就是提取图像的边缘。对二维函数f(x, y)求偏微分。
Sobel、Scharr 和 Laplacian…算子
3.Ganny原理 高斯滤波滤除噪声 计算像素点梯度强度和方向 应用Sobel等算子卷积计算梯度值和方向 G G x 2 G y 2 θ arctan ( G y G x ) ( θ → 0 , 45 , 90 , 135 ) G\sqrt{G_x^2G_y^2}\\ \theta\arctan(\frac{G_y}{G_x})(\theta \rightarrow 0,45,90,135) GGx2Gy2 θarctan(GxGy)(θ→0,45,90,135) 应用极大值抑制 A 点位于边缘垂直方向。渐变方向与边缘垂直。 B 点和 C 点处于梯度方向。因此用点 B 和 C 检查点 A看它是否形成局部最大值。如果是这样则考虑下一阶段否则它被抑制归零。 双阈值检测确定边缘 选择两个阈值关于阈值的选取方法在扩展中进行讨论根据高阈值得到一个边缘图像这样一个图像含有很少的假边缘但是由于阈值较高产生的图像边缘可能不闭合未解决这样一个问题采用了另外一个低阈值。 在高阈值图像中把边缘链接成轮廓当到达轮廓的端点时该算法会在断点的8邻域点中寻找满足低阈值的点再根据此点收集新的边缘直到整个图像边缘闭合。
4.Canny()
C: void Canny(InputArray image,OutputArray edges, double threshold1, double threshold2, int apertureSize3,bool L2gradientfalse )InputArray类型的image输入图像即源图像填Mat类的对象即可且需为单通道8位图像。OutputArray类型的edges输出的边缘图需要和源图片有一样的尺寸和类型。double类型的threshold1第一个滞后性阈值。double类型的threshold2第二个滞后性阈值。int类型的apertureSize表示应用Sobel算子的孔径大小其有默认值3。bool类型的L2gradient一个计算图像梯度幅值的标识有默认值false。
(5).霍夫变换
最基本的霍夫变换是从黑白图像中检测直线(线段)
霍夫变换(Hough Transform)是图像处理中的一种特征提取技术该过程在一个参数空间中通过计算累计结果的局部最大值得到一个符合该特定形状的集合作为霍夫变换结果。
1.霍夫线变换
1.1 原理
图像空间点——参数空间线图像空间点共线——参数空间线交点 参数空间点——图像空间线
1.2 HoughLines()
void HoughLines(InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn0, double stn0 )第二个参数 存储线条每线条由 $ (\rho , \theta) $表示第三个参数 rho 距离精度(步长) $ \rho $第四个参数 theta 角度精度 $ \theta $
2.霍夫圆变换
2.1 原理 ( x 0 − a ) 2 ( y 0 − b ) 2 R 2 (x_0-a)^2(y_0-b)^2R^2 (x0−a)2(y0−b)2R2
从平面坐标到极坐标转换三个参数 C ( a 0 , b 0 , r ) C(a_0,b_0,r) C(a0,b0,r) a0 ,b0是圆心图像空间点—参数空间圆锥图像空间点共圆—圆锥截面圆交点, 三维空间点—图像空间圆
2.2 HoughCircles()
基本原理
噪声敏感——中值滤波基于图像梯度检测边缘发现可能圆心从可能圆心计算最佳半径
霍夫梯度法
计算图像中每个像素点的梯度方向和大小。可以使用Sobel算子或其他边缘检测算法来计算梯度。对于每个像素点根据其梯度方向和大小在参数空间中生成可能的直线或圆的参数。对于直线参数通常是斜率和截距对于圆参数通常是圆心坐标和半径。对于每个生成的参数组合统计通过该参数组合的像素点数量。这可以通过累加器数组来实现数组的每个元素对应一个参数组合值表示通过该参数组合的像素点数量。根据累加器数组的结果找到可能存在的直线或圆的参数。可以设置一个阈值来筛选出像素点数量大于阈值的参数组合即为检测到的直线或圆。根据检测到的直线或圆的参数在原始图像上绘制检测结果。
void HoughCircles(InputArray image,OutputArray circles, int method, double dp, double minDist, double param1100,double param2100, int minRadius0, int maxRadius0 )method : CV_HOUGH_GRADIENT dp : 如果dp 1时累加器和输入图像具有相同的分辨率。如果dp2累加器便有输入图像一半那么大的宽度和高度。 minDist 为霍夫变换检测到的圆的圆心之间的最小距离 param1 传递给canny边缘检测算子的高阈值 param2 越小可以检测更多根本不存在的圆越大能通过检测的圆更加接近完美的圆形
connectedComponentsWithStats()
int cv::connectedComponentsWithStats(InputArray image,OutputArray labels,OutputArray stats,OutputArray centroids,int connectivity 8, int ltype CV_32S );retval : 返回值是连通区域的数量。 labels : labels是一个与image一样大小的矩形labels.shape image.shape其中每一个连通区域会有一个唯一标识标识从0开始。 stats stats会包含5个参数分别为x,y,h,w,s。分别对应每一个连通区域的外接矩形的起始坐标x,y外接矩形的wide,heights其实不是外接矩形的面积实践证明是labels对应的连通区域的像素个数。 centroids : 返回的是连通区域的质心。
五、轮廓
(1).查找绘制
预处理
灰度化使用cv::cvtColor()图像去噪使用高斯滤波cv::Gaussian()二值化使用cv::Threshold()形态学处理cv::morphologyEx()
其中灰度化可以将3通道图像转化为单通道图像以便进行二值化门限分割去噪可以有效剔除图像中的异常独立噪点二值化是为轮廓查找函数提供单通道图像形态学的某些处理通常可以剔除细小轮廓联通断裂的轮廓。
1.findContours()
void cv::findContours(InputOutputArray image,OutputArrayOfArrays contours,OutputArray hierarchy,int mode,int method, Point offset Point()) contours : 输出检测到的轮廓。由若干个cv::Point类型的点组成了单个轮廓std :: vector cv :: Point 再由若干个轮廓组成输入图像中的全部轮廓std::vectorstd :: vector cv :: Point hierarchy : 输出轮廓级别信息。Hierarchy为可选输出变量是std::vector cv::Vec4i类型的向量每个元素都是一个4个int值构成的向量。它具有与轮廓数量一样多的元素。例如第i个轮廓 hierarchy[i][0]hierarchy[i][0]hierarchy[i][2]和hierarchy[i][3]依次为第i个轮廓的[Next, Previous, First_Child, Parent]即轮廓i相同等级的下一轮廓、前一轮廓第一个子轮廓和父轮廓上一级轮廓的索引号即contours向量中的轮廓序号。如果轮廓i没有下一个前一个父级或嵌套轮廓则层次结构[i]的相应元素将为负数。
2.drawContours()
void cv::drawContours(InputOutputArray image,InputArrayOfArrays contours,int contourIdx,const Scalarcolor,int thickness 1,int lineType LINE_8,InputArray hierarchy noArray(),int maxLevel INT_MAX, Point offset Point() ) contouridx : 待绘制轮廓序号
(2).层级结构
OpenCV中每个轮廓都有自己的信息关于它是什么层次结构谁是它的子轮廓谁是它的父轮廓等.OpenCV将它表示为四个int值的数组类型为cv::Vec4i4个int值
[NextPreviousFirst_ChildParent]
hierarchy数组在OpenCV中是一个四维数组hierarchy数组的四维结构为 [轮廓索引, 轮廓信息, 关系信息]
Next
Next表示同一级别的下一个轮廓索引。例如在我们的图片中取出轮廓-0。同一水平的下一个轮廓是轮廓-1。 所以简单地说Next 1。类似地对于轮廓-1next是轮廓-2。 所以Next 2。 轮廓-2的同一级别没有下一个轮廓所以轮廓-2的Next -1。轮廓-4呢它与轮廓-5处于同一水平。所以它的下一个轮廓是轮廓-5所以轮廓-4的Next 5。
Previous
Previous表示同一级别的上一个轮廓索引。例如轮廓-1的上一个轮廓在同一级别中为轮廓-0。 类似地对于轮廓-2它的上一个轮廓是轮廓-1。而对于轮廓-0没有先前的所以把它的Previous -1。
First_Child
First_Child表示当前轮廓的第一个子轮廓索引。例如对于轮廓-2子轮廓是轮廓-2a。因此轮廓-2的First_Child为轮廓-2a的相应索引值。轮廓-3a呢它有两个子轮廓。但hierarchy参数只记录第一个子轮廓因此它是轮廓-4的索引值。因此对于轮廓-3aFirst_Child 4。
Parent
Parent表示当前轮廓的父轮廓索引。对于轮廓-4和轮廓-5它们的父轮廓都是轮廓-3a。对于轮廓-3a它的父轮廓是轮廓-3依此类推。
(3).筛选轮廓
首次查找轮廓有许多中间有空洞的轮廓不符合要求下面就通过遍历每一个轮廓的hierarchy级别参数的第3第4个参数来找到那些有子轮廓或者有父轮廓的轮廓并删除之。注意向量迭代器的使用删除后会返回下一个向量的指针此外contours与hierarchy元素需要同步删除和并递增迭代器以保持编号对应关系否则会删错。
std::vectorstd::vectorcv::Point::iterator itc contours.begin();
std::vectorcv::Vec4i::iterator itc_hierarchy hierarchy.begin();
int i 0;
while(itc_hierarchy ! hierarchy.end())
{if (hierarchy[i][2] 0 || hierarchy[i][3] 0){itc contours.erase(itc);itc_hierarchy hierarchy.erase(itc_hierarchy);}else{i;itc;itc_hierarchy;}
}(4).凸包
凸包外观看起来与轮廓逼近相似但并非如此(在某些情况下两者可能提供相同的结果)。一般而言凸曲线是始终凸出或至少平坦的曲线。如果在内部凸出则称为凸度缺陷。例如检查下面的手的图像。红线显示手的凸包。双向箭头标记显示凸度缺陷这是船体与轮廓线之间的局部最大偏差。
void cv::convexHull (InputArray points,OutputArray hull,bool clockwise false,bool returnPoints true ) clockwise方向标记。如果为True则输出凸包为顺时针方向。否则其方向为逆时针方向。returnPoints默认情况下为True。然后返回船体点的坐标。如果为False则返回与船体点相对应的轮廓点的索引。 gpos_idimg-85t64AsU-1709221922430)
六、Functions
(1).createTrackbar()
C: int createTrackbar(conststring trackbarname, conststring winname,int* value, int count, TrackbarCallback onChange0,void* userdata0);第一个参数const string类型的trackbarname表示轨迹条的名字 第二个参数const string类型的winname窗口的名字 第三个参数int* 类型的value一个指向整型的指针表示滑块的位置。并且在创建时滑块的初始位置就是该变量当前的值。 第四个参数int类型的count表示滑块可以达到的最大位置的值。滑块最小的位置的值始终为0。 第五个参数TrackbarCallback类型的onChange默认值0。这是一个指向回调函数的指针每次滑块位置改变时这个函数都会进行回调。并且这个函数的原型必须为void XXXX(int,void*);其中第一个参数是轨迹条的位置第二个参数是用户数据看下面的第六个参数。如果回调是NULL指针表示没有回调函数的调用仅第三个参数value有变化。 第六个参数void*类型的userdata他也有默认值0。这个参数是用户传给回调函数的数据用来处理轨迹条事件。如果使用的第三个参数value实参是全局变量的话完全可以不去管这个userdata参数。
(2).SetMouseCallback() void setMousecallback(const string winname, MouseCallback onMouse, void* userdata0)// winname:窗口的名字// onMouse:鼠标响应函数回调函数。指定窗口里每次鼠标时间发生的时候被调用的函数指针。void on_Mouse(int event, int x, int y, int flags, void* param);// event是 CV_EVENT_*变量之一// x和y是鼠标指针在图像坐标系的坐标不是窗口坐标系 // flags是CV_EVENT_FLAG的组合 param是用户定义的传递到setMouseCallback函数调用的参数。event 具体说明如下 EVENT_MOUSEMOVE 0 //滑动 EVENT_LBUTTONDOWN 1 //左键点击 EVENT_RBUTTONDOWN 2 //右键点击 EVENT_MBUTTONDOWN 3 //中键点击 EVENT_LBUTTONUP 4 //左键放开 EVENT_RBUTTONUP 5 //右键放开 EVENT_MBUTTONUP 6 //中键放开 EVENT_LBUTTONDBLCLK 7 //左键双击 EVENT_RBUTTONDBLCLK 8 //右键双击 EVENT_MBUTTONDBLCLK 9 //中键双击
flags 具体说明如下 EVENT_FLAG_LBUTTON 1 //左键拖曳 EVENT_FLAG_RBUTTON 2 //右键拖曳 EVENT_FLAG_MBUTTON 4 //中键拖曳 EVENT_FLAG_CTRLKEY 8 //(8~15)按 Ctrl 不放 EVENT_FLAG_SHIFTKEY 16 //(16~31)按 Shift 不放 EVENT_FLAG_ALTKEY 32 //(32~39)按 Alt 不放