zoukankan      html  css  js  c++  java
  • opencv笔记

    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



    18 Mat  和  IplImage 互转
    IplImage* pBinary = &(IplImage(src)); 
    cv::Mat img(pImg,0);


    19 打开 ip摄像机
        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.
     
    如: 
    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 直方图均衡化
    equalizeHist( frame_gray, frame_gray );
    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为我们内建了一些变量用于访问线程格、线程块的尺寸和索引等信息,它们是:

          1. gridDim:代表线程格(grid)的尺寸,gridDim.x为x轴尺寸,gridDim.y、gridDim.z类似。拿上图来说,
    它的gridDim.x = 3,gridDim.y = 2,gridDim.z = 1;
          2. blockIdx:代表线程块(block)在线程格(grid)中的索引值,拿上图来说,Block(1,1)的索引值为:blockIdx.x = 1,blockIdx.y = 1;
          3. blockDim:代表线程块(block)的尺寸,blockDIm.x为x轴尺寸。拿上图来说,注意到Block(1,1)包含了4 * 3个线程,因此blockDim.x = 4, blockDim.y = 3;
          4. threadIdx:代表线程的索引,如Thread(3,2),则threadIdx.x=3,threadIdx.y=2;
     
    26.3  <<<>>> 中参数的含义
     
     
    26.4 opencv 中出现 mutiple 的解决方法

    #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);

  • 相关阅读:
    GitHub 实现多人协同提交代码并且权限分组管理
    前端第一篇文章-http标准
    介绍Android电量
    音频编码格式
    PPT
    Word
    HTML 之 JavaScript
    HTML 之 CSS
    HTML 之 HTTP 协议(请求协议以及响应协议)
    HTML 之 标签
  • 原文地址:https://www.cnblogs.com/luoyinjie/p/7219326.html
Copyright © 2011-2022 走看看