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

来源:互联网 发布:linux的图形界面工具 编辑:程序博客网 时间:2024/05/22 16:53

Outline:

1.CV背景介绍
2.OpenCV基础
3.图像的基本操作:遍历图像,ROI选取
4.Python环境搭建
5.机器学习在CV中的应用:KNN与Kmeans

一、什么是Computer Vision(CV)

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

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

二、图像处理库

图像处理库:
OpenCV
CxImage ~= OpenCV1.0
CImg 显示做的好
FreeImage 大量使用指针读速度快,读到图像的信息全
HALCON 商用精密测量

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

(三)OpenCV安装配置

安装配置参考浅墨博客:博客链接
因为之前学过OpenCV,所以就安装配置了好多次了,但我一般都是用学校的电脑,笔记本上没配。本来配置很顺手了,这次遇到一个问题:无法打开文件“opencv_ml249d.lib”。找了半天没找出配置步骤上出什么问题,看浅墨博客找到了解决方法:项目->属性管理器->Debug|Win32->Microsoft.Cpp.Win32.userDirectories中的属性页面->连接器->常规里面的附加库目录中加入相应的lib文件目录。
还有就是,属性管理器在图->其他管理器里里,老找不着。。。

可安装插件ImageWatch:下载链接,能显示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)Mat pImgRect = pImg.clone();
(2)Mat pImgRect = 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比较流行或者3.5都可以)

python教程:基础教程网站

Anaconda下载:
官网下载
官网下载容易出现下载失败!真的不要尝试在官网下载。下了好几次,动不动就是链接断开下载失败的。。

(划重点)从国内清华大学开源软件镜像站进行下载并配置镜像。链接
推荐一个下载安装教程
致Python初学者们 - Anaconda入门使用指南 链接地址

Jupyter notebook 使用教程

(六)机器学习

1、机器学习:要随机地观测数据,要随机地对观测数据进行采样,要学习数据的性质(也叫做特征feature)以及属性(通常叫做label,它是属于哪个类别的),然后再来预测新的未知数据的属性。在机器学习,通常把数据分为两部分,一部分是训练集training,一部分是测试集test,两部分相互独立。

2、监督式学习(除了数据以外,还有额外的属性,如feature&label):分类和回归
分类:输出是离散的。例:根据各种特征,将一个群体,分成几种。
回归:输出连续的。例:根据年龄体重,预测身高。
监督学习主要是分类,尽量把问题转化为分类问题。

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

(七)KNN(分类)

Knn的应用背景是:手写字符识别
最常用的数据库 http://yann.lecun.com/exdb/mnist/

当求未知项目的类别时,先探测周围项目是什么类别。转换成算法:
第一种实现思路:
用一条线把这两个区域分开,叫决策边界,把所有数据一分为二。但是要求数据必须是线性可分的,如果数据复杂的时候,就要做非线性的变换了,把数据映射到多维空间中,让它成为线性可分的。

第二种思路:
就是Knn算法:参考待测点周围最近的k个数据的label是什么,将出现频率最高的label作为该点的预测结果。

Knn作为一种机器学习的算法也分为两部分
训练:把训练集和标签全部存储,比如说给下图这样一个训练图像,把下图和它的label(5)存储,把这些存储完,它就学习完毕了。

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

劣势:没有训练,测试的时候需要把所有训练集都拿来和测试的数据一一比对,比对就涉及距离问题,测试两个向量的距离。
优势:简单。当数据不是线性的时候,表现比其他分类器好一些。

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

示例:
//补充

(八)K-means(聚类)

聚类算法

K-means

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

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

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


Example:颜色降维