<学习opencv> opencv 概述及初探

Opencv3 当前模块

  Core    //  该模块包含Opencv库的基础结构以及基本操作.

  Improc     //   图像处理模块,包含基本的图像转换,包括滤波以及类似的卷积操作.

         High                 //   包括三个部分,分别为imcodecs,videoio,以及highui.

           包含用于显示图像或者简单的输入的用户交互函数.可视为轻量级的Windows UI工具包.

         Video              //   视频模块,包含读取和写视频流的函数.

         Calib3d         //   该模块包含校准单个,双目以及多个相机的算法实现.

         Feature2d    //   该模块包含用于检测,描述以及匹配特征点的算法.
         Objdectect  //    该模块包含检测特定目标,比如人脸或者行人的算法;也可以训练检测器并用来检测其他物体.

         Ml                   //    本身完备的机器学习模块,包含大量的机器学习算法实现并且这些算法都能和Opencv的数据类型自然交互.

         Flann            //     快速最邻近库,该库包含在数据集中进行最邻近搜索的相关算法

         GPU              //     GPU模块主要是函数在CUDA GPU上的优化实现,

                                        有一些仅用于GPU的功能,其中一些函数能够返回很好的结果,但是需要足够好的计算资源.

                                        若硬件没有GPU,则不会有什么提升.

        Photo        //   这个一个新的模块,包含计算摄影学的一些函数工具

        Stitching  //   该模块是一个精巧的图像拼接流程实现

        Nonfree    (在opencv3.0中,被移到opencv_contrib/xfeatures2d)

            //  该模块包含一些受到专利保护的或者受到使用限制的(比如SIFT算法)

                               这些算法被隔离到他们自己的模块中,以表明你需要做一些特殊的工作,才可以在商业产品中使用它们.

        Contrib  (在opencv3.0中,被融合到opencv_contrib) //该模块包含了一些新的,但还没有被集成进Opencv库里的东西

        Legacy  (在opencv3.0中,被取消)  //该模块包含了一些老的尚未完全被取消的东西

        Ocl          (在opencv3.0中,被取消,取而代之的是T-API)  //一个较新的模块,可以认为它和GPU模块相似,实现了开放并行编程的Khronos OpenCL标准.

                        虽然现在模块的特性比GPU模块少很多,但Ocl模块的目标是提供可以运行在任何GPU或者其他可以搭载Khronos的并行设备.

OpenCV 贡献库(opencv_contrib)

包含的模块列表

  Dnn                 //   深度神经网络
         Face               //    人脸识别

  Text               //   文本检测以及识别,基于许多开源的OCR算法

         Rgbd            //    处理由Kinect或者其他深度传感器(或者简单的由双目匹配得到的)获取的RGB+深度图像

         Bioinspired        //   一些基于生物学启发的视觉技术

         ximgproc和xphoto    //   先进的图像处理以及计算摄影学方法

         Tracking             //   现代目标追踪算法

OpenCV 头文件

../include/opencv2/opencv.hpp 包含各个模块的头文件:

旧式C风格头文件

#include "opencv2/core/core_c.h"                        // 旧式C风格的结构以及运算
#include "opencv2/imgproc/imgproc_c.h"       // 旧式C风格的图像处理函数
#include "opencv2/highgui/highgui_c.h"          //  旧式C风格的显示,滑动条,鼠标操作以及输入输出相关

新式C++风格头文件

#include "opencv2/core/core.hpp"                  //C++数据结构和算术例程
#include "opencv2/flann/miniflann.hpp"          //近似最近邻匹配函数
#include "opencv2/imgproc/imgproc.hpp"          //特定于处理和恢复照片的算法
#include "opencv2/video/photo.hpp"              //视频跟踪和背景分割例程
#include "opencv2/features2d/features2d.hpp"    //二维功能跟踪支持
#include "opencv2/objdetect/objdetect/hpp"      //级联人脸检测器;检测的SVM;系首长;平面斑块检测器
#include "opencv2/calib3d/calib3d.hpp"          //校准和立体声
#include "opencv2/ml/ml.hpp"                    //机器学习:聚类和模式识别
#include "opencv2/highgui/highgui.hpp"          //C++图像显示,滑块,按钮,鼠标,I/O
#include "opencv2/contrib/contrib.hpp"          //用户贡献的代码:肉体检测,模糊均值平移跟踪,自旋图像,自相似特征

[注]若使用头文件opencv.hpp来包含所有可能在openCV函数中用到的头文件,这样的好处是使用简单不用单独使用某一模块的头文件,但带来的弊端是这会减慢编译的速度.相反,如果只针对图像处理相关的函数使用某一个头文件,那么程序用于编译的时间会少上很多.
具体导入方式,还需视情况而定.

例程

DEMO1 - 显示图片

#include <opencv2/opencv.hpp> //包含每个支持的Open函数的文件

int main()
{
    //读取图像(支持图像格式:JPEG,PNG,BMP,DIB,JPE,PBM,PGM,PPM,SR)
    Mat img = imread("") ;    //可处理单通道,多通道,整数值,浮点值
    if (img.empty()) return -1 ;     
    //建立窗口并指定名称  WINDOW_AUTOSIZE/0 设置窗口属性
    namedWindow("img",WINDOW_AUTOSIZE) ;    
    //要求程序停下来等待按键 
    waitKey(0) ;                
    //关闭窗口并释放任何相关的内存使用情况
    destroyWindow("img") ;      
}

DEMO2 - 视频 用于从磁盘中播放视频

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

using namespace cv ;

int main()
{
    namedWindow("Video",WINDOW_AUTOSIZE) ;
    VideoCapture cap ;      //实例化视频捕捉对象
    cap.open(string("")) ;  //捕获对象被赋予一个字符串,其中包含要打开的视频路径和文件名
    Mat frame ;             //实例化一个数据对象保存帧
    for (;;){               //进入死循环
        cap >> frame ;      //不断从捕获对象流中逐帧读取视频文件
        if (frame.empty()) break ;  //检查数据是否实际从视频文件中读取  若没有 则退出视频
        imshow("Video",frame) ;     //如果是视频帧 成功读入,则显示通过imshow()
        if (waitKey(33) >= 0) break ; //如果在此期间按下某个键,退出读取循环。否则继续循环
    }
    return ;
}

DEMO3 - 将轨迹栏滑块添加到基本查看器窗口,以便在视频文件中移动

#include "opencv4/opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.cpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <fstream>

using namespace std ;
using namespace cv ;
int g_slider_position = 0 ;     //[1]定义全局变量保持轨迹栏滑块的位置状态
//以单步模式开始
int g_run = 1;              //实例化对象,只要它不等于1,就会显示新的帧
int g_dontset = 0 ;          //允许在不触发单步模式情况下更新轨迹栏的位置

VideoCapture g_cap ;            //[2]回调访问捕获对象,也定义为全局变量


void onTrackbarSlide(int pos, void*) { //传递pos为新的轨迹栏位置
    g_cap.set(CAP_PROP_POS_FRAMES,pos) ;      //使用新请求的位置来实际将视频回放推进到新位置
    if (!g_dontset) g_run = 1 ;               //将程序设置为在下一个新帧进入后进入单步模式
    g_dontset = 0 ;
}

int main(int argc, char ** argv){
    namedWindow("Video",WINDOW_AUTOSIZE) ;
    g_cap.open(string(argv[1])) ;

    //这些例程允许我们配置VideoCapture对象的各种属性
    //用来确定视频中的帧数以及视频图像的宽度和高度
    int frames = (int)g_cap.get(CAP_PROP_FRAME_COUNT) ; //传递CAP_PROP_FRAME表明以帧为单位设置读取位置
    int tmpw = (int)g_cap.get(CAP_PROP_FRAME_WIDTH) ;   //宽度
    int tmph = (int)g_cap.get(CAP_PROP_FRAME_HEIGHT) ;  //高度
    cout << "视频:" << frames << "维度框架:(" << tmpw << "," << tmph << ")" << endl ;

    //创建轨迹栏
    //指定标签和放置轨迹栏的窗口。将变量绑定到轨迹栏,轨迹蓝的最大值(视频中的帧数),移动滑块时的回调
    createTrackbar("Position","Video",&g_slider_position,frames,onTrackbarSlide) ;

    Mat frame ; //实例化一个数据对象保存帧
    for (;;){
        if (g_run!=0){
            g_cap >> frame ;
            if (frame.empty()) break ;
            int current_pos = (int)g_cap.get(CAP_PROP_POS_FRAMES) ;
            g_dontset = 1 ;     //设置参数以便下一个轨迹栏回调不会进入单步模式

            //调用轨迹栏回调来更新显示的滑块轨迹栏的位置
            setTrackbarPos("Position","Video",current_pos) ;

            imshow("Video",frame) ;
            g_run -= 1 ;    //保持单步模式或者让视频根据用户按键设置的先前状态运行
        }
        char c = (char)cv::waitKey(10) ;
        if (c = 's') //如果按下S,计入单步模式,允许读取单帧
        {g_run = 1; cout << "单步,运行=" << g_run << endl ;}

        if (c = 'r') //如果按下R,进入连续视频模式
        {g_run = -1; cout << "运行模式,运行=" << g_run << endl ;}
        if (c == 27) break ;   //如果按下ESC,程序终止
    }
    return 0 ;
}

DEMO4 - 在图像显示在屏幕上之前加载并平滑图像

#include <opencv2/opencv.hpp>

void Smooth(const Mat&image){
    
    namedWindow("in",WINDOW_AUTOSIZE) ;     //创建输入窗口
    namedWindow("out",WINDOW_AUTOSIZE) ;    //创建输出窗口
    imshow("in",image) ;    //显示输入图像
    Mat out ;   //实例化输出图像矩阵
    //图像平滑处理
    /*GaussianBlur() blur() median() bilateralFilter()*/
    GaussianBlur(image,out,Size(5,5),3,3) ;     //输入图像被5*5高斯卷积滤波器模糊并写入out
    GaussianBlur(out,out,Size(5,5),3,3) ;       //out用做输入输出,进行双重模糊
    imshow("out",out) ;                         //显示生成模糊图像
    waitKey(0) ;                                //等待按键
}

DEMO5 - 使用pyrDown()创建一个新的图像,该图像是输入图像宽度和高度的一半

#include <opencv2/opencv.hpp>

int main(int argc, char ** argv)
{
    Mat img1, img2 ;
    namedWindow("img1",WINDOW_AUTOSIZE) ;
    namedWindow("img2",WINDOW_AUTOSIZE) ;
    string path = "" ;
    img = imread(path) ;
    imshow("img1",img1) ;
    pyrDown(img1, img2) ;   //下采样
    imshow("img2",img2) ;
    waitKey(0) ;
}

DEMO6 - Canny边缘检测器将其输出写入单通道(灰度)图像

#include <opencv2/opencv.hpp>

int main(int argc, char ** argv)
{

    Mat img_rgb, img_gry,img_cny ;
    namedWindow("Grey",WINDOW_AUTOSIZE) ;
    namedWindow("Canny",WINDOW_AUTOSIZE) ;

    string path = "" ;
    img_rgb = imread(path) ;

    cvtColor(img_rgb,img_gry,COLOR_BGR2GRAY) ;  //转换颜色空间到 BGB到灰度
    imshow("gray",img_gry) ;

    Canny(img_gry,img_cny,10,100,3,true) ;      //边缘检测器生成的图像是输入图像的全尺寸
    imshow("canny",img_cny) ;

    waitKey(0) ;
    return 0 ;
}

DEMO7 - 将金字塔向下运算符和canny子程序组合

cvtColor(img_rgb,img_gry,COLOR_BGR2GRAY)
pyrDown(img_gry,img_pyr) ;
pyrDown(img_pyr,img_pyr2) ;
Canny(img_pyr2, img_cny, 10,100,3,true) ;

DEMO8 - 获取和设置像素

int x = 16 , y = 32 ;

Vec3b intensity = img_rgb.at<Vec3b>(y,x) ;
uchar blue = intensity[0] ;
uchar green = intensity[1] ;
uchar red = intensity[2] ;

cout << "At(x,y)=(" << x << "," << y 
     << "):(blue,green,blue)=(" 
     << (unsigned int)blue << "," 
     << (unsigned int)green << ","
     << (unsigned int)red << ")" << endl ;

cout << "Gray pixel there is:" << (unsigned int)img_gry.at<uchar>(y,x) << endl ;

x /= 4; y /= 4 ;
cout << "Pyramid2 pixel there is:" << 
     << (unsigned int)img_pyr2.at<uchar>(y,x) << endl ;
    
img_cny.at<uchar>(x,y) = 128 ; //将canny像素设置为128

DEMO9 - 相同的对象可以从相机或者文件加载视频

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std ;
using namespace cv ;

int main(int argc,char ** argv)
{
    namedWindow("Video",WINDOW_AUTOSIZE) ;
    VideoCapture cap ;
    string path = "" ;
    if (argc == 1)
    {
        cap.open(0) ;   //打开第一台相机
    } else {
        cap.open(path) ;
    }
    if (!cap.isOpened()){   //检查是否成功
        cerr << "Coundn't open capture." << endl ;
        return -1 ;
    }
}

DEMO10 - 用于读取彩色视频并写出对数极化变换后的视频

//从VideoReader对象中逐帧读取视频,转换帧以对象极坐标格式,并将对象坐标帧一次一个写入新的视频文件
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std ;
using namespace cv ;

int main(int argc,char ** argv){

    namedWindow("Video",WINDOW_AUTOSIZE) ;
    namedWindow("Log_Polar",WINDOW_AUTOSIZE) ;

    VideoCapture capture(argv[]1) ;
    //注意:可以通过将摄像头ID作为int来从摄像机捕获

    double fps = capture.get(CAP_PROP_FPS) ;
    Size size(
        (int)capture.get(CAP_PROP_FRAME_WIDTH) ,
        (int)capture.get(CAP_PROP_FRAME_HEIGHT) 
    );

    VideoWriter writer ;
    /*参数说明 */
    //argv[2] 新文件的文件名
    //CV_FOURCC('M','J','P','G') 用于压缩视频流的视频编解码器
    //fps 重放帧速率
    //size 使用图像的大小
    writer.open(argv[2],CV_FOURCC('M','J','P','G'),fps, size) ;

    Mat logpolar_frame,bgr_frame ;
    for (;;){
        capture >> bgr_frame ;
        if (bgr_frame.empty()) break ;
        imshow("bgr_frame",bgr_frame) ;
        
        logPolar(
            bgr_frame,         //输入颜色框
            logpolar_frame,     //输出对数极坐标框架
            Point2f(            //对数极坐标变换的中心点
                bgr_frame.cols / 2,     //x
                bgr_frame.rows / 2      //y
            ),
            40,                     //幅度(比例参数)
            WARP_FILL_OUTLIERS      //用“零”填充异常值
        );

        imshow("Log_Polar",logpolar_frame) ;
        writer << logpolar_frame ;
        if (c == 27) break ;    
    }
    capture.release() ;
}
posted @ 2021-03-10 14:22  Xu_Lin  阅读(257)  评论(0编辑  收藏  举报