1.Mat 的几种初始化方法:
通过外部指针赋值:
Mat m(height, width,CV_8UC(3),rgb) ;
初始化为任意像素:
Mat M(2,2, CV_8UC3, Scalar(0,0,255));
初始化为0:
Mat mask = Mat::zeros( pic.size(),CV_8UC1 );
imread 的第二个参数
>0 读取三通道
=0 读取灰度图
<0 按照其本来的通道读取,可以有alpha通道
Mat m = (Mat<double>(3,3)<<1,2,3,4,5,6,7,8,9);
Mat 增加行:t1.push_back( Mat( 1,t1.cols,t1.type(),Scalar(0) ) );
2. Mat 读像素值,和写像素值
//read
Vec3b p= m[0].at<Vec3b>(j,i);第一个参数是行,第二个参数是列
//write
_m[i].at<Vec3b>(k,j) = p[3];
unsigned char* p = &(dst.data[(j*width + i)*3 ]) ;
p[0],p[1], p[2] 分别代表BGR
Float 类型
Mat img1(ROWS , COLS , CV_32FC1);
for (int i=0; i<ROWS ; i++)
{
float* pData1=img5.ptr<float>(i);
for (int j=0; j<COLS ; j++)
{
pData1[j] = 3.2f;
}
}
3.
画矩形 :rectangle( m, out, Scalar(0,0,255), 1, 8, 0 );
画圆: circle( img, center, WINDOW_WIDTH/32 , Scalar(0,0,255) , thickness, linType );
画线 :line(picture,a,center,Scalar(255,0,0));
写字 : putText(Mat&img, const string& text, Point org, intfontFace, double fontScale, Scalar color, intthickness=1, int lineType=8, bool bottomLeftOrigin=false)
如果 thickness等于 CV_FILLED则表示填充整个矩形。
4. 存储图片
char filename[100];
sprintf( filename,"template_%d.png",i );
vector<int> params;
params.push_back(CV_IMWRITE_PNG_COMPRESSION);
params.push_back(9);
imwrite(filename, _m, params );
5. 将logo加到原图上
addWeighted(roi, 0.5, logo, 0.3, 0., roi);
1、 第1个参数,输入图片1,
2、第2个参数,图片1的融合比例
3、第3个参数,输入图片2
4、第4个参数,图片2的融合比例
5、第5个参数,偏差
6、第6个参数,输出图片
6. 颜色空间转换
cvtColor( src,dst, COLOR_YUV420sp2BGR)
7. 通道分离
split( src, channels );
img0 = channels.at(0);
8. 通道合并
9 直方图均衡化
equalizeHist( src, dst );
10 二值图像中寻找轮廓
findContours()
11 绘制轮廓
drawContours()
12 图片修复
inpaintMask = Mat::zeros(srcImage1.size(), CV_8U);
inpaint(srcImage1, inpaintMask, inpaintedImage, 3, CV_INPAINT_TELEA);
13 获取运算时间
unsigned long begin = getTickCount();
... ...
unsigned long interv = getTickCount()-begin;
int val = 1000*(interv)/getTickFrequency() ;
14 腐蚀和膨胀
//Point(-1,-1),内核中心点。省略时为默认值。
//iterations:膨胀次数。省略时为默认值1。
dilate(binary,bg,cv::Mat(),cv::Point(-1,-1),6)
腐蚀函数为erode, 参数和上述一样
开运算 : 先腐蚀后膨胀,可以用于消除白色噪声
闭运算:把黑色的噪声编程白色,用于扩大选区
15:waitKey()
waitKey()函数的功能是不断刷新图像,频率时间为delay,单位为ms。
返回值为当前键盘按键值。
所以显示图像时,如果需要在imshow(“xxxx”,image)后吐舌头加上waitKey()为大于等于0的数即可,那么程序将会停在显示函数处,不运行其他代码;直到键盘值为key的响应之后。
16 BGR转灰度图
17 bgr转换为lab空间为何转换后是0-255?
-
L = L * 255 100, a = a + 128, b = b + 128
const std::string videoStreamAddress = "rtsp://192.168.1.156:554/ch1/1"; if(!vcap.open(videoStreamAddress)) {}
打开视频VideoCapture inputVideo("test.mp4");打开摄像头VideoCapture cap(0);cap.set( CV_CAP_PROP_FRAME_WIDTH,640);cap.set( CV_CAP_PROP_FRAME_HEIGHT,480 );if(!cap.isOpened()){}
20 查找面积最大的轮廓,绘制轮廓, 匹配轮廓矩形
//【4】定义轮廓和层次结构
Mat dstImage( src.size(),CV_8U );
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours( color_mask, contours, hierarchy,
CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE );hierarchy : 中的4个值分,第一个表示后一个轮廓,第二个表示前一个轮廓,第三个表示子轮廓,第四个表示父轮廓//找出面积最大的轮廓,并绘制。
for(int index = 0; index >= 0; index = hierarchy[index][0] )
{
Scalar color( rand()&255, rand()&255, rand()&255 );
//Scalar color( rand()&255, rand()&255, rand()&255 );
double g_dConArea = abs(contourArea(contours[index], true));
cout<<g_dConArea<<endl;
if( g_dConArea > 10000 )
drawContours( dstImage, contours, index, color, CV_FILLED, 8, hierarchy );
}
//查找矩形
RotatedRect box = minAreaRect( dstImage );
—CV_RETR_EXTERNAL:只检测外轮廓。忽略轮廓内部的洞。
—CV_RETR_LIST:检测所有轮廓,但不建立继承(包含)关系。
—CV_RETR_TREE:检测所有轮廓,并且建立所有的继承(包含)关系。也就是说用CV_RETR_EXTERNAL和CV_RETR_LIST方法的时候hierarchy这个变量是没用的,因为前者没有包含关系,找到的都是外轮廓,后者仅仅是找到所哟的轮廓但并不把包含关系区分。用TREE这种检测方法的时候我们的hierarchy这个参数才是有意义的。事实上,应用前两种方法的时候,我们就用findContours这个函数的第二种声明了。
—CV_RETR_CCOMP:检测所有轮廓,但是仅仅建立两层包含关系。外轮廓放到顶层,外轮廓包含的第一层内轮廓放到底层,如果内轮廓还包含轮廓,那就把这些内轮廓放到顶层去。
21 putText 写文字 函数的参数解释
void putText(Mat&img, const string& text, Point org, intfontFace, double fontScale, Scalar color, intthickness=1, int lineType=8, bool bottomLeftOrigin=false)
参数为
- img – 图像矩阵
- text – string型 文字内容
- org – 文字坐标,以左下角为原点
- fontFace – 字体类型 (包括 FONT_HERSHEY_SIMPLEX,FONT_HERSHEY_PLAIN, FONT_HERSHEY_DUPLEX, FONT_HERSHEY_COMPLEX,FONT_HERSHEY_TRIPLEX, FONT_HERSHEY_COMPLEX_SMALL, FONT_HERSHEY_SCRIPT_SIMPLEX, orFONT_HERSHEY_SCRIPT_COMPLEX,)
- fontScale –字体大小
- color – 字体颜色
- thickness – 字体粗细
- lineType – Line type. See the line for details.
- bottomLeftOrigin – When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner.
如:equalizeHist( frame_gray, frame_gray );putText(img, "blog.csdn.net/boksic" , Point(0, int(img.rows*0.9)), CV_FONT_HERSHEY_COMPLEX,img.cols/400, cvScalar(200, 200, 200, 0));
22. 点积 A.dot(B)
对应为的乘积 A.mul(B)
叉乘 A*B
23 直方图均衡化24. 人脸检测face_cascade->detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));faces--被检测物体的矩形框向量组;1.1 : 1.1即每次搜索窗口依次扩大10%2: minNeighbors--表示构成检测目标的相邻矩形的最小个数(默认为3个)。
如果组成检测目标的小矩形的个数和小于 min_neighbors - 1 都会被排除。
如果min_neighbors 为 0, 则函数不做任何操作就返回所有的被检候选矩形框,
这种设定值一般用在用户自定义对检测结果的组合程序上;
flags--要么使用默认值,要么使用CV_HAAR_DO_CANNY_PRUNING,如果设置为CV_HAAR_DO_CANNY_PRUNING,那么函数将会使用Canny边缘检测来排除边缘过多或过少的区域,
minSize和maxSize用来限制得到的目标区域的范围。
25 预编译指令判断 opencv版本
#define CV_VERSION_MAJOR 3
#define CV_VERSION_MINOR 3
#define CV_VERSION_REVISION 1
26 opencv CUDA / CUDA 笔记
26.1
// 在CUDA 中执行函数 语法:函数名称<<<block 数目, thread 数目, shared memory 大小>>>(参数...);
sumOfSquares << <1, 1, 0 >> >(gpudata, result);
26.2 thread block
dim3 blocks(32,32);
dim3 threads(16,16);(与dim3 threads(16,16,1)等价)
dim3是神马?dim3是一个内置的结构体,dim3结构变量有x,y,z,表示3维的维度,如果只需要二维,定义时只需将第三元缺省或置为1。
kernelfun<<<blocks, threads>>>();
blocks表示Gird里有二维的32*32个block,而每个block中又用了16*16的二维的thread组。好吧,我们这个施令动用了262144个线程
26.3
在内核函数内部,CUDA为我们内建了一些变量用于访问线程格、线程块的尺寸和索引等信息,它们是:
它的gridDim.x = 3,gridDim.y = 2,gridDim.z = 1;
![](https://images2017.cnblogs.com/blog/1135673/201712/1135673-20171221134841490-759822742.png)
#include <opencv2/cudev.hpp>
#include "opencv2/core/cuda/common.hpp"
#include <opencv2/core/cuda.hpp>
#include <opencv2/core/cuda_stream_accessor.hpp>
这些文件只能包含到.cu文件里去,千万不要包含到头文件中。
global 函数的声明和定义都要加“__global__” 修饰符
device函数只需要加声明上就行了,定义不需要加
global 和 device 函数要放在两个cu文件中定义 不然会出奇葩的错误 , 我也不知道是为什么。。
27 漫水填充 https://www.cnblogs.com/xixixing/p/6040732.html
28翻转、旋转和转置
28.1 翻转 flip
C++: void flip(InputArray src, OutputArray dst, int flipCode)
参数介绍:
src: 即输入矩阵
dst: 即输出矩阵
flipCode: 旋转码,即控制函数对矩阵进行怎样的旋转。当参数flipCode=0时,将对矩阵沿X轴方向翻转;当flipCode>0时,将对矩阵沿Y轴方向翻转;当flipCode<0时,将对矩阵沿XY轴方向翻转。
28.2 转置
transpose(m1, m3);
28.3 旋转90度
29 resize 参数
- INTER_NEAREST - 最邻近插值
- INTER_LINEAR - 双线性插值,如果最后一个参数你不指定,默认使用这种方法
- INTER_AREA - resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire’-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method.
- INTER_CUBIC - 4x4像素邻域内的双立方插值
- INTER_LANCZOS4 - 8x8像素邻域内的Lanczos插值
31特征点、单应性矩阵等
31.1
Mat H = findHomography(obj, scene, RANSAC); // 根据一一对应的点集obj 和 scene 找出单应性矩阵H
perspectiveTransform(obj_corners, scene_corners, H); // 根据输入点和单应性矩阵H 计算投影区域 obj_corners 和 scene_corners 为已知
31.1 opencv3 中 特征点检测, 和2不一样了
opencv3.3 中SurfFeatureDetector、SurfDescriptorExtractor、BruteForceMatcher这三个的使用方法已经和原先2.4版本前不一样了。
使用方法示例如下:
cv::Ptr<Feature2D> detector = xfeatures2d::SURF::create(400);
std::vector<KeyPoint> keypoints_object, keypoints_scene;
detector->detect(img_object, keypoints_object);
detector->detect(img_scene, keypoints_scene);
Mat descriptors_object, descriptors_scene;
detector->compute(img_object, keypoints_object, descriptors_object);
detector->compute(img_scene, keypoints_scene, descriptors_scene);
32 随机数
RNG可以产生3种随机数
RNG(int seed) 使用种子seed产生一个64位随机整数,默认-1
RNG::uniform( ) 产生一个均匀分布的随机数
RNG::gaussian( ) 产生一个高斯分布的随机数
RNG::uniform(a, b ) 返回一个[a,b)范围的均匀分布的随机数,a,b的数据类型要一致,而且必须是int、float、double中的一种,默认是int。
RNG::gaussian( σ) 返回一个均值为0,标准差为σ的随机数。
33 计时
cv::TickMeter tm; tm.reset(); tm.start(); std::vector<Window> faces = detector.DetectFace(img); tm.stop(); std::cout << "Image: " << i << std::endl; std::cout << "Time Cost: "<< tm.getTimeMilli() << " ms" << std::endl;
34 opencv 各版本的差异
http://www.cnblogs.com/shine-lee/p/9884551.html
35 opencv 静态库
IlmImfd.lib
ippicvmt.lib
ippiwd.lib
ittnotifyd.lib
libjasperd.lib
libjpegd.lib
libpngd.lib
libtiffd.lib
libwebpd.lib
zlibd.lib
opencv_core340d.lib
opencv_highgui340d.lib
opencv_imgproc340d.lib
opencv_imgcodecs340d.lib
IlmImf.lib
ippicvmt.lib
ippiw.lib
ittnotify.lib
libjasper.lib
libjpeg.lib
libpng.lib
libtiff.lib
libwebp.lib
zlib.lib
opencv_core340.lib
opencv_highgui340.lib
opencv_imgproc340.lib
opencv_imgcodecs340.lib
35
cv::convertScaleAbs()用于实现对整个图像数组中的每一个元素,进行如下操作:
36 matchTemplate 参数解释
https://blog.csdn.net/qq_18343569/article/details/48004497
37 霍夫直线检测
HoughLinesP参数分析
void HoughLinesP(InputArray image,OutputArray lines, double rho, double theta, int threshold, double minLineLength=0,double maxLineGap=0 )
image为输入图像,要求是单通道,8位图像
lines为输出参数,4个元素表示,即直线的起始和终止端点的4个坐标(x1,y1),(x2,y2)
rho为距离分辨率,一般为1
heta为角度的分辨率,一般CV_PI/180
threshold为阈值,hough变换图像空间值最大点,大于则执行
minLineLength为最小直线长度(像素),即如果小于该值,则不被认为是一条直线
maxLineGap为直线间隙最大值,如果两条直线间隙大于该值,则被认为是两条线段,否则是一条。
38 reshap 函数
C++: Mat Mat::reshape(int cn, int rows=0) const
参数比较少,但设置的时候却要千万小心。
cn: 表示通道数(channels), 如果设为0,则表示保持通道数不变,否则则变为设置的通道数。
rows: 表示矩阵行数。 如果设为0,则表示保持原有的行数不变,否则则变为设置的行数。
39: depth
上面是一个 3 X 4 X 6 的矩阵,假设其数据类型为 CV_16SC4,也就是 short 类型
- M.dims == 3 ; M.channels() == 4 ; M.elemSize1() == sizeof(short) == 2 ;
- M.rows == M.cols == –1;
- M.elemSize() == M.elemSize1() * M.channels() == M.step[M.dims-1] == M.step[2] == 2 * 4 == 8;
- M.step[0] == 4 * 6 * M.elemSize() == 192;
- M.step[1] == 6 * M.elemSize() == 48;
- M.step[2] == M.elemSize() == 8;
- M.step1(0) == M.step[0] / M.elemSize() == 48 / 2 == 96 (第一维度(即面的元素个数) * 通道数);
- M.step1(1) == M.step[1] / M.elemSize() == 12 / 2 == 24(第二维度(即行的元素个数/列宽) * 通道数);
- M.step1(2) == M.step[2] / M.elemSize() == M.channels() == 4(第三维度(即元素) * 通道数);
40 mat 表示3维矩阵
float* d1=new float[a*b*c]; for(int i=0;i<a*b*c;i++) d1[i] =(float)i; Mat myND=Mat(3,size,CV_32F,d1);
https://www.cnblogs.com/phoenixdsg/p/6908029.html
41 二范数:
double l2 = cv::norm(diffm, cv::NORM_L2);
//l2 = sqrt( a00*a00 + ... + ann*ann );
42 threshold
cv::threshold(src, src, 128, 255,cv::THRESH_TOZERO); //小于128 设置为0 cv::threshold(src, src, 128, 255, cv::THRESH_TOZERO_INV); //大于128设置为0
cv::threshold(src, src, 64, 255, cv::THRESH_BINARY); // 二值化 , 128 为分界点
43 ipp 库 最小值滤波
ippiFilterMinBorder_8u_C1R(src.data, w, dst.data, w, { w,h }, { 17,17 }, ippBorderMirror, 0, tmp);