计算机视觉(一)

1. CV背景介绍

 

两个项目整理:

  OpenBR http://openbiometrics.org/  人脸识别
  http://git.oschina.net/easypr/EasyPR   车牌定位

 

2.opencv库的完全解析

  Clion + opencv3.2

  安装方法

         https://blog.csdn.net/bskfnvjtlyzmv867/article/details/78940472

3.图像的基本操作:遍历图像、ROI选取

  

  Opencv 中都是用Mat进行矩阵管理

#include "cv.hpp"
using namespace cv;
using namespace std;
#include <iostream>

int main() {
    Mat M(3,2,CV_8UC3,Scalar(0,0,255));
//    cout << "Hello, World!" <<endl;
    cout << M <<endl;
    return 0;
}

M=
[ 0, 0, 255, 0, 0, 255;
0, 0, 255, 0, 0, 255;
0, 0, 255, 0, 0, 255]

 

 

遍历图像的六种方法:
1.
uchar value = grayim.at<uchar>(i,j);
for( int i = 0; i < grayim.rows; ++i)
for( int j = 0; j < grayim.cols; ++j )
grayim.at<uchar>(i,j) = (i+j)%255;
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; } 2.
彩色图像:
cv::Mat Iterator_<uchar> grayit, grayend; for( colorit = colorbegin = im.begin<uchar>(), colorend = colorim.end<uchar>(); colorit != colorend; ++colorit) {

  *colorit[0] = rand()%255;
  *colorit[1] = rand()%255;
  *colorit[2] = rand()%255;
}
灰度图像:
cv::Mat Iterator_<uchar> grayit, grayend;
for( grayit = grayim.begin<uchar>(), grayend =
grayim.end<uchar>(); grayit != grayend; ++grayit)
*grayit = rand()%255;
3.
for( int i = 0; i < grayim.rows; ++i)
{
//获取第 i 行首像素指针
uchar * p = grayim.ptr<uchar>(i);
//对第 i 行的每个像素(byte)操作
for( int j = 0; j < grayim.cols; ++j )
p[j] = (i+j)%255;
}
4.
Mat M(600, 800, CV_8UC1);
for( int i = 0; i < M.rows; ++i)
{
uchar * p = M.ptr<uchar>(i);
for( int j = 0; j < M.cols; ++j )
{
double d1 = (double) ((i+j)%255);
M.at<uchar>(i,j) = d1;
double d2 = M.at<double>(i,j);
}
}
5.
查找表的方式
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(I, lookUpTable, Out); 6.
地址寻址去访问 addr(Mi0,i1,…im
-1) = M.data + M.step[0] * i0 + M.step[1] * i1 + … + M.step[m-1] * im-1 (其中 m = M.dims M的维度) 

 

4.Python环境搭建+语法

   python基础教程: 

  http://www.runoob.com/python/python-tutorial.html

5.机器学习在CV中的应用: KmeansKNN

   监督学习

    回归、分类

   无监督学习  

    聚类

   KNN:  

目标:分类未知类别案例。

输入:待分类未知类别案例项目。已知类别案例集合D ,其中包含 j个已知类别的案例

输出:项目可能的类别

#include<stdio.h>
#include<stdlib.h>
#include<cv.h>
#include<highgui.h>
#include<ml.h>
#include<time.h>

using namespace cv;

int readFlippedInteger(FILE *);

int main()
{
    FILE *fp = fopen("..\\data\\train-images.idx3-ubyte", "rb");

    FILE *fp2 = fopen("..\\data\\train-labels.idx1-ubyte", "rb");

    if (!fp || !fp2)
    {
        //    cout << "Files not Found" << endl;
        return 0;
    }

    int magicNumber = readFlippedInteger(fp);
    int numImages = readFlippedInteger(fp);
    int numRows = readFlippedInteger(fp);
    int numCols = readFlippedInteger(fp);

    fseek(fp2, 0x08, SEEK_SET);

    int size = numRows*numCols;

    Mat trainingVectors(numImages, size, CV_32FC1);
    Mat trainingLabels(numImages, 1, CV_32FC1);
    //CvMat *trainingVectors = cvCreateMat(numImages, size, CV_32FC1);
    //CvMat *trainingLabels = cvCreateMat(numImages, 1, CV_32FC1);

    uchar *temp = new uchar[size];
    //unsigned char *temp = new unsigned char[size];

    uchar tempClass = 0;

    for (int i = 0; i < numImages; i++)
    {
        fread((void*)temp, size, 1, fp);
        fread((void*)(&tempClass), sizeof(uchar), 1, fp2);
        trainingLabels.at<float>(i, 0) = tempClass;
        Mat img(numRows, numCols, CV_32FC1);
        for (int k = 0; k < size; k++)
        {
            trainingVectors.at<float>(i, k) = temp[k];
            img.at<float>(k / numCols, k%numCols) = temp[k];
        }
        imshow("data", img);
        //waitKey(2);
    }

    KNearest knn(trainingVectors, trainingLabels);
    printf("Maximum k: %d\n", knn.get_max_k());
    

    fclose(fp);
    fclose(fp2);
    delete[] temp;


    fp = fopen("..\\data\\t10k-images.idx3-ubyte", "rb");
    fp2 = fopen("..\\data\\t10k-labels.idx1-ubyte", "rb");

    magicNumber = readFlippedInteger(fp);
    numImages = readFlippedInteger(fp);
    numRows = readFlippedInteger(fp);

    numCols = readFlippedInteger(fp);

    fseek(fp2, 0x08, SEEK_SET);
    CvMat *testVectors = cvCreateMat(numImages, size, CV_32FC1);
    CvMat *testLabels = cvCreateMat(numImages, 1, CV_32FC1);
    CvMat *actualLabels = cvCreateMat(numImages, 1, CV_32FC1);
    temp = new uchar[size];
    tempClass = 1;
    CvMat *currentTest = cvCreateMat(1, size, CV_32FC1);
    CvMat *currentLabel = cvCreateMat(1, 1, CV_32FC1);
    int totalCorrect = 0;

    for (int i = 0; i<numImages; i++)
    {

        fread((void*)temp, size, 1, fp);

        fread((void*)(&tempClass), sizeof(uchar), 1, fp2);

        actualLabels->data.fl[i] = (float)tempClass;

        for (int k = 0; k<size; k++)
        {
            testVectors->data.fl[i*size + k] = temp[k];
            currentTest->data.fl[k] = temp[k];
        }
        knn.find_nearest(currentTest, 5, currentLabel);

        testLabels->data.fl[i] = currentLabel->data.fl[0];

        if (currentLabel->data.fl[0] == actualLabels->data.fl[i])
            totalCorrect++;
    }
    printf("Time: %d Accuracy: %f ", (int)time, (double)totalCorrect * 100 / (double)numImages);
}

int readFlippedInteger(FILE *fp) {
    int ret = 0;    
    uchar *temp;
    temp = (uchar*)(&ret);    
    fread(&temp[3], sizeof(uchar), 1, fp);    
    fread(&temp[2], sizeof(uchar), 1, fp);    
    fread(&temp[1], sizeof(uchar), 1, fp);    
    fread(&temp[0], sizeof(uchar), 1, fp);     
    return ret;
}

 

 

K-means:

  欧式距离进行计算。数据集取与分类之间欧式距离的平均值作为新的分类点,一直到循环迭代,中心变化很小便停止了。

// colorReduce.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <vector>

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>


void colorReduce(cv::Mat& image, int div = 64)
{
    int nl = image.rows;                    // number of lines
    int nc = image.cols * image.channels(); // number of elements per line

    for (int j = 0; j < nl; j++)
    {
        // get the address of row j
        uchar* data = image.ptr<uchar>(j);

        for (int i = 0; i < nc; i++)
        {
            // process each pixel
            data[i] = data[i] / div * div;
        }
    }
}
void keamsCplus(cv::Mat& input, cv::Mat& output, int clusterCount = 4){
    cv::Mat src;
    input.copyTo(src);
    //step 1 : map the src to the samples
    cv::Mat samples = src.reshape(1, src.total());
    samples.convertTo(samples, CV_32F);
    //step 2 : apply kmeans to find labels and centers
    cv::Mat labels;
    int attempts = 5;//try 5 times, choose the best result
    cv::Mat centers;
    cv::kmeans(samples, clusterCount, labels,
        cv::TermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS,
        10, 0.01),
        attempts, cv::KMEANS_PP_CENTERS, centers);

    //step 3 : map the centers to the output
    // Now convert back into uint8, and make original image
    cv::Mat new_image(src.size(), src.type());
    cv::Mat red_samples(src.total(), 3, CV_8U);
    centers.convertTo(centers, CV_8U);
    for (int i = 0; i < src.total(); i++)
    {
        int clusterIdx = labels.at<int>(i);
        centers.row(clusterIdx).copyTo(red_samples.row(i));
    }
    new_image = red_samples.reshape(3, src.rows);
    new_image.copyTo(output);
}

int main(int argc, char* argv[])
{
    // Load input image (colored, 3-channel, BGR)
    cv::Mat input = cv::imread("boldt.jpg");
    if (input.empty())
    {
        std::cout << "!!! Failed imread()" << std::endl;
        return -1;
    }

    int divideWith = 64;
    uchar table[256];
    for (int i = 0; i < 256; ++i)
        table[i] = (uchar)(divideWith * (i / divideWith));
    cv::Mat lookUpTable(1, 256, CV_8U);
    uchar*p = lookUpTable.data;
    for (int i = 0; i < 256; i++)
        p[i] = table[i];
    cv::Mat result;
    LUT(input, lookUpTable, result);
    ///////////////////
    //kmeans
    cv::Mat resultKmeans;
    keamsCplus(input, resultKmeans,8);
    //////////////////////
    colorReduce(input);
    ///////////////////////
    cv::imshow("Color Reduction", input);
    cv::imwrite("output.jpg", input);
    cv::waitKey(0);

    return 0;
}

 

posted @ 2018-12-04 16:54  吕晓宁  阅读(365)  评论(0编辑  收藏  举报