• 1、图像处理基础


    大纲

    1、图像处理基础

    2、图像的特征提取

    3、机器视觉中的几何学

    1)坐标变换与视觉测量

    2)3D计算机视觉

    4、机器视觉中的机器学习方法与数据处理

    1)图像识别

    2)图像搜索

    推荐书:计算机视觉---算法与应用。

    Fundamental of Computer Vision(计算机视觉基础)

    1、什么是计算机视觉?

    计算机视觉的目的就是写计算机程序来解释图像。

    图像处理(image processing)输入的是图像输出的还是图像

    计算机视觉(computer vision)输入的是图像输出的是对图像的理解

    应用:

    目标跟踪和识别、人脸识别、增强现实(AR-Augmented reality)(,以前叫virtual reality,虚拟现实,其实就是是否引入真实场景,AR就是在我们看到的基础之后,增加一些三维的场景,比如对物体的解释等等)、机器人学(识别物体、估计运动和位姿)、工业检测、字符设别等等

    2、open libraries/projects(开源库或者工程)

    opencv官网:http://opencv.org/

    语言:c++,c,python和java接口

    平台:windows,linux,Mac OS,IOS和Android

    库用得比较多的:CxImage,CImage,FreeImage

    HALCON:http://www.halcon.com

    ,它是商用的图像处理的库,收费的

    开源项目

    项目一:人脸识别

    项目二:车牌识别

    mobileye公司的产品可以关注一下!!

    这种发布的版本只能看源代码不能调试源代码!!!

    2015为VC14

    3、opencv安装配置

    环境变量配置好之后,接下来在工程中进行配置在属性管理器中进行一次配置,以后就不用再配置了:

    先新建一个空的工程,然后再进行下面的配置!!!

    对于依赖项部分,在3.0之前要添加很多依赖项,但是在3.0之后只添加如上的两个库文件。

    下面环境安装完成!!!!!!!!!!

    介绍一个插件

    Image Watch,这个插件也是2.4之后才有的,它是非常有用的东西

    程序模版

    认识图像

    图像数据在内存中的存储

    opencv是从元素[0,0]开始且按行存储,而matlab是从[1,1]开始表示第一个元素且按列存储。

    在opencv里面最常用的就是Mat类型,它既可以表示数据data,也可以表示图像类。

    Mat定义一个矩阵,如下解释

    Mat M(3,2,CV_8UC3,Scalar(0,0,255));

    cout<<"M="<<endl<<" "<<M<<endl;

    上面创建了一个高为3,宽为2的矩阵,且是3通道(C3)的8位无符号整数(8U),初始值为(0,0,255)

    由于上面的符号"<<"被重构了,所以把这个矩阵打印出来,如上面所示。

    我们定义了3行2列的矩阵,由于channel是3,2乘3是六列,但其实矩阵的维度还是3*2,在内存中占了6个字节.???
    Scalar是从Vector类衍生出来的类,他可以存储4个元素,一次性最多可以赋值4个值,除了RGB三个通道之外,还有一个表示透明度的α参数。

    上图中的变量refcount表示引用计数,表示有多少个指针指向了同一个data区域,它在内存中占数据区域的最后4位。

    Mat常用的构造函数

    举个例子:

    //定义一个变量,通过函数Imread来读取图片lena.jpg,1是指的它是彩色就读取彩色图像,是灰度图像就读取灰度图像。

    cv::Mat pImag = imread("lena.jpg",1);

    //定义了一个矩形区域,左上角坐标(180,200),后面两个数是矩阵的宽、高度(200,200),图像坐标

    cv::Rect rect(180, 200, 200, 200);

    也是先x坐标后y坐标。

    //定义了一个roi的变量,如前面的构造函数Mat::Mat(const Mat& m,const Rect& roi),这时候只是使roi指向了rect这个地址,不是深拷贝

    cv::Mat roi = cv::Mat(pImag,rect);

    //又定义了一个变量pImgRect,它把原来的图像进行深层拷贝clone(),赋值给该变量,且带有矩形框。还有一个copyto函数也是深拷贝

     cv::Mat pImgRect = pImag.clone();

    //在原始图形上勾勒出对应的矩形框void rectangle(Mat& img, Rect rec, const Scalar& color, int thickness=1, int lineType=8, int shift=0 );img图像.pt1矩形的一个顶点。pt2矩形对角线上的另一个顶点color线条颜色 (RGB) 或亮度(灰度图像 )(grayscale image)。thickness组成矩形的线条的粗细程度。取负值时(如 CV_FILLED)函数绘制填充了色彩的矩形。line_type线条的类型。见cvLine的描述shift坐标点的小数点位数。

    cv::rectangle(pImgRect,rect,cv::Scalar(0,255,0),2);

    cv::imshow("original image with rectangle",pImgRect);

    imshow("roi",roi);

    cv:waitkey();

    注意,深拷贝与浅拷贝(注意上面的构造函数都是浅拷贝)

    上面左边是浅拷贝,上面的构造函数都是浅拷贝;右边是深拷贝

    测试

    eye表示对角矩阵,默认都是单通道!

    像素值的读写-1

    grayim.at<uchar>(i,j),这里的at表示在那个位置,表示对一个灰度图像在i行j列拿到这个元素的灰度值。

    上面是一个单通道的图像,下面是一个三通道的图像,

    先处理行再处理列。

    有一个Vec3b类,表示是3个元素,b是unchar型,

    typedef Vec3b   vec<uchar,3>

    上面的具体实现以及结果

    for (int i = 0; i < grayim.rows; ++i)
      for (int j = 0; j < grayim.cols; ++j)
       grayim.at<uchar>(i, j) = (i + j) % 255;
     imshow("grayim",grayim);
     for (int i = 0; i < colorim.rows; ++i)
      for (int j = 0; j < colorim.cols; ++j)
      {
       Vec3b pixel;
       pixel[0] = i % 255;//blue
       pixel[1] = j % 255;//green
       pixel[2] = 0;//Red
       colorim.at<Vec3b>(i, j) = pixel;
      }
     imshow("colorim", colorim);

    像素值的读写2

    Iterator迭代器可以方便遍历所有的元素,以便于对矩阵元素进行遍历

    具体实现

    cv::MatIterator_<uchar> grayit, grayend;
        for (grayit = grayim.begin<uchar>(), grayend = grayim.end<uchar>(); grayit != grayend; ++grayit)
            *grayit = rand() % 255;
        imshow("grayim", grayim);
    
        MatIterator_<Vec3b> colorit, colorend;
        for (colorit = colorim.begin<Vec3b>(), colorend = colorim.end<Vec3b>(); colorit != colorend; ++colorit)
        {
            (*colorit)[0] = rand() % 255;//Blue
            (*colorit)[1] = rand() % 255;//green
            (*colorit)[2] = rand() % 255;//red
        }
        imshow("colorim", colorim);

    上面用的是ptr的模板函数,用于选中一行的首元素地址。

     具体代码:

    for (int i = 0; i < grayim.rows; ++i)
        {
            //获取第i行首像素指针
            uchar *p = grayim.ptr<uchar>(i);
            //对第i行的每个像素操作
            for (int j = 0; j < grayim.cols; ++j)
                p[j] = (i + j+5) % 255;
        }
    
        imshow("grayim1", grayim);
    
        for (int i = 0; i < colorim.rows; ++i)
        {
            Vec3b *p = colorim.ptr<Vec3b>(i);
            //对第i行的每个像素操作
            for (int j = 0; j < colorim.cols; ++j)
            {
                p[0] = i % 255;//blue
                p[1] = j % 255;//green
                p[2] = 0;//Red
                colorim.at<Vec3b>(i, j) = *p;
            }
        }
        imshow("colorim1", colorim);
    View Code
  • 相关阅读:
    11月20号
    11月17号
    11月21号
    11月19号
    第一章 Windows下前端代码打包编译
    每日日报
    每日日报
    每日日报
    学习Java的第十三天
    学习Java的第十六天——随机数
  • 原文地址:https://www.cnblogs.com/gary-guo/p/6259746.html
Copyright © 2020-2023  润新知