Advertisement

计算机视觉笔记(一) 初探计算机视觉

阅读量:

Outline:

1. 计算机视觉领域概述
2. OpenCV入门知识
3. 图像的基本操作包括遍历图像以及进行 ROI 选择。
4. Python开发环境搭建
5. 机器学习技术在计算机视觉领域的应用涵盖多种算法如 KNN 和 Kmeans 等。

一、什么是Computer Vision(CV)

计算机视觉的目的:通过写程序来解释图片。

图像处理:输入图像,输出图像
计算机视觉:输入图像,输出图像的理解

二、图像处理库

本节介绍几种常用的图像处理库:首先是最经典的OpenCV是一个功能强大的计算机视觉库。其次CxImage等价于OpenCV 1.0版本。此外CImg库在显示效果上表现优异。FreeImage则以其大量使用指针快速读取速度快而著称,并且能够完整地读取图像信息。最后Halcon则主要用于商业精密测量领域。

项目:
OpenBR 人脸识别项目
EasyPR 识别车牌

(三)OpenCV安装配置

参考博客中的安装配置说明:博客链接

该插件支持查看Mat文件内容,并能方便地进行调试工作

(四)图像处理基础知识

一、彩色图像存储:BGR

二、Mat
1、常用构造函数

2、全零矩阵、全一矩阵、对角线为1矩阵

复制代码
    Mat Z = Mat::zeros(2, 3, CV_8UC1);
    cout << "Z=" << Z << endl;
    Mat O = Mat::ones(2, 3, CV_32F);
    cout << "O=" << O << endl;
    Mat E = Mat::eye(2, 3, CV_64F);
    cout << "E=" << E << endl;

3、ROI:
1)、感兴趣区域的设置

复制代码
    #include <iostream>
    #include "opencv2/opencv.hpp"
    using namespace std;
    using namespace cv;
    
    int main(int argc, char *argv[])
    {
    Mat pImg = imread("Lena.jpg", 1);
    Rect rect(180, 200, 200, 200);//(x,y)=(180,200),w=200,height=200
    Mat roi = Mat(pImg, rect);
    Mat pImgRect = pImg.clone();//深拷贝
    rectangle(pImgRect, rect, Scalar(0, 255, 0), 2);
    imshow("original image with rectangle", pImgRect);
    imshow("roi", roi);
    waitKey();
    return 0;
    }

运行结果

2)、浅拷贝、深拷贝
深拷贝两种方法:
(1)通过调用pImg.clone()函数来生成矩形矩阵;
(2)通过调用pImg.copyto()函数来实现矩阵的复制;

这里写图片描述

4、像素值的读写

1).at(i, j)方式

复制代码
    //灰度图像
    Mat grayim(512, 512, CV_8UC1);
    uchar value = grayim.at<uchar>(0, 0);
    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("gray", grayim);
    
    //彩色图像
    Mat colorim(512, 512, CV_8UC3);
    for (int i = 0; i < colorim.rows; i++)
        for (int j = 0; j < colorim.cols; j++)
        {
            Vec3b pixel;
            pixel[0] = i % 255;//B
            pixel[1] = j % 255;//G
            pixel[2] = 0;      //R
            colorim.at<Vec3b>(i, j) = pixel;
        }
    imshow("color", colorim);

2)迭代器

复制代码
    //灰度图像
    Mat grayim(512, 512, CV_8UC1);
    Mat_<uchar>::iterator grayit;
    for (grayit = grayim.begin<uchar>(); grayit < grayim.end<uchar>(); grayit++)
        *grayit = rand() % 255;
    imshow("gray", grayim);
    
    //彩色图像
    Mat colorim(512, 512, CV_8UC3);
    Mat_<Vec3b>::iterator colorit;
    for (colorit = colorim.begin<Vec3b>(); colorit < colorim.end<Vec3b>(); colorit++)
    {
        (*colorit)[0] = rand() % 255;
        (*colorit)[1] = rand() % 255;
        (*colorit)[2] = rand() % 255;
    }
    imshow("color", colorim);

3)、指针按行遍历

复制代码
    Mat grayim(512, 512, CV_8UC1,Scalar(0));
    for (int i = 0; i < grayim.rows; i++)
    {
        uchar *p = grayim.ptr<uchar>(i);
        for (int j = 0; j < grayim.cols; j++)
            p[j] = rand() % 255;
    }
    imshow("gray", grayim);

4)、Mat_类

复制代码
    Mat M(512, 512, CV_8UC1);
    Mat_<uchar> M1 = (Mat_<uchar>&)M;
    for (int i = 0; i < M1.rows; i++)
    {
        uchar *p = M1.ptr(i);
        for (int j = 0; j < M1.cols; j++)
        {
            double d1 = (double)((i + j) % 255);
            M1(i, j) = d1;
            double d2 = M1(i, j);
        }
    }

5)、一般有映射关系时使用

查找表(降低灰度级,提高运算速度)

量化公式,降低灰度级

复制代码
    Mat M(512, 512, CV_8UC1);
    Mat_<uchar> M1 = (Mat_<uchar>&)M;
    for (int i = 0; i < M1.rows; i++)
    {
        uchar *p = M1.ptr(i);
        for (int j = 0; j < M1.cols; j++)
        {
            double d1 = (double)((i + j) % 255);
            M1(i, j) = d1;
            double d2 = M1(i, j);
        }
    }
    Mat Out;
    int divideWith = 10;
    uchar table[256];
    for (int i = 0; i < 256; i++)
        table[i] = divideWith*(i / divideWith);
    
    Mat lookUpTable(1, 256, CV_8U);
    uchar *p = lookUpTable.data;
    for (int i = 0; i < 256; i++)
        p[i] = table[i];
    LUT(M, lookUpTable, Out);
    imshow("origin", M);
    imshow("result", Out);
这里写图片描述

5、数据获取与存储

1)imread

复制代码
    Mat pImg = imread("Lena.jpg", 1);
    //flag=0,强制转换为单通道,flag=1不改变

2)imwrite
8U的可以转化为图像 看手册
直接覆盖

6、video读写类

1)读视频

复制代码
    //读视频
    //VideoCapture cap(0);  //摄像头id
    VideoCapture cap("video.avi");  //本地视频
    if (!cap.isOpened())
    {
        cerr << "Can not open a camera or file." << endl;
        return -1;
    }
    Mat edges;
    namedWindow("edges", 1);
    for (;;)
    {
        Mat frame;
        cap >> frame;
        if (frame.empty())
            break;
    
        imshow("frame", frame);
    
        if (waitKey(30) >= 0)
            break;
    }
    
    waitKey();

2)写视频

复制代码
    Size s(320, 240);
    VideoWriter writer = VideoWriter("myvideo.avi", CV_FOURCC('M', 'J', 'P', 'G'), 25, s);
    if (!writer.isOpened())
    {
        cerr << "Can not creat a video." << endl;
        return -1;
    }
    Mat frame(s, CV_8UC3);
    for (int i = 0; i < 100; i++)
    {
        writer << frame;
    }

(五)python

涉及到深度学习与机器学习相关的内容,所以要学习一下python

Python环境的安装建议采用Anaconda搭配Ipython(或Jupyter)以及PyScripter工具包(其中版本号为2.7较为常见且适用)。

Python学习入门:推荐访问基础学习网站Runoob Python Tutorial

Anaconda 官方提供了一个便捷的下载页面:https://www.continuum.io/downloads

(划重点)通过国内清华大学开源软件镜像站进行下载并配置镜像。

Jupyter notebook 使用教程

(六)机器学习

在机器学习中通过随机采样来获取观测数据以了解其特征并推断分类结果以便预测新样本所属类别及其属性将原始数据划分为两个互不重叠的部分其中一部分用于模型训练另一部分用于性能评估这两部分的数据处理过程需确保相互独立以避免信息泄露和偏差影响

除了基于数据外还包含额外属性如features and labels的监督学习主要用于解决分类与回归问题。其中分类任务的目标是将输入映射到有限且明确的类别中;而回归任务的目标是预测连续型目标变量。在大多数情况下,监督学习问题被建模为一个分类问题。

3、非监督式学习(没有额外的label):聚类和核密度估计
聚类:K-means算法。

(七)KNN(分类)

KNN算法的主要应用场景是字符识别技术。其中最常被引用的数据集为MNIST数据库

当需要识别未知项目的类型时, 首先需要确定其邻近项目所属的类别.将其转化为具体的计算步骤:
第一种具体实施思路是:通过一条直线将这两个区域区分开来,并称为决策边界;这样就能够将所有数据分成两部分;然而这种方法仅适用于数据本身具有的属性能够被分割的情况;如果遇到更为复杂的场景,则需要引入非线性的变换方法;具体而言就是将原始的数据映射到更高维度的空间中进行分析。

另一种思路:当采用Knn算法时,则是根据待测样本周围k个邻居的数据特征进行分析。此时,在观察对象附近选取距离最近的k个样本,并统计这些样本中各类别出现的频次,在此基础上确定待测样本的预测类别。

Knn属于机器学习算法,并分为两个主要部分。
在进行分类任务时:
第一步是将所有训练数据及其对应的标签进行存储。
举例来说,在处理一个这样的训练图像时:
将该图像及其对应的标签(假设为5)进行存储。
完成所有数据的学习后,
模型就完成了分类任务的学习过程。

测试:提供测试集,没有标签,让算法猜这是什么,要指定K的大小。

劣势:未经过训练,在测试阶段需要将所有训练样本集合用于比较分析与测试样本数据进行逐一进行对比分析,并涉及到计算两个向量之间的距离的问题。优势:简洁性。当数据呈现非线性特征时,其分类效果优于其他方法

参数K的选择一般不大于20。

示例:
//补充

(八)K-means(聚类)

聚类算法

K-means

主要做法:选取一个点,对于一堆数据,把它聚成n类。

示例:我们有一堆数据,指定三个数据,把它们聚成三类。

复制代码
    K1,K2,K3指定之后,找到离它最近的一个数据作为center,进行label,把数据分成三个label,在相同label的数据中求均值,定义均值作为新的中心,进行循环迭代,直到收敛为止,停止条件是中心变化很小或者是所有数据的label已经不变了。

Example:颜色降维

全部评论 (0)

还没有任何评论哟~