opencv自测程序(算法函数)

#include "PictureAlgorithm.h"

PictureAlgorithm::PictureAlgorithm()
{

}

PictureAlgorithm::~PictureAlgorithm()
{

}

/* 灰度直方图 */
Mat PictureAlgorithm::test1()
{
    Mat image = imread("../x64/Debug/picture/2.jpg", IMREAD_GRAYSCALE);
    imshow("4", image);

    int channels[1] = {0}; //0表示第一通道
    int bins[1] = {256};
    float hRange[2] = {0, 255};
    const float *ranges[1] = {hRange}; //必须是const
    
    Mat calcDst; //输出的直方图数组
    calcHist(&image, 1, channels, Mat(), calcDst, 1, bins, ranges, true, false); //计算直方图的数据

    int histW = 512;
    int histH = 400;
    int binW = cvRound((double)histW / bins[0]); //返回跟参数最接近的整数值,即四舍五入
    Mat histImage = Mat::zeros(408, 560, CV_8UC3);

    Mat yHist = calcDst.clone();

    normalize(calcDst, calcDst, 0, histImage.rows, NORM_MINMAX, -1, Mat()); //归一化到直方图的高

    //直方图
    for(int i=1; i(i-1));
        int x2 = binW * i;
        int y2 = histH - cvRound(calcDst.at(i));
        line(histImage, Point(x1, y1), Point(x2, y2), Scalar(12,23,200), 1, LINE_4, 0);
    }

    //x坐标轴
    for(int i=0; i bgrPlane;
    split(image, bgrPlane);

    int channels[1] = {0};
    int bins[1] = {256};
    float hRange[2] = {0, 255};
    const float *ranges[1] = {hRange}; //必须是const

    Mat bgrCalc[3];
    calcHist(&bgrPlane[0], 1, channels, Mat(), bgrCalc[0], 1, bins, ranges, true, false);
    calcHist(&bgrPlane[1], 1, channels, Mat(), bgrCalc[1], 1, bins, ranges, true, false);
    calcHist(&bgrPlane[2], 1, channels, Mat(), bgrCalc[2], 1, bins, ranges, true, false);

    int histW = 512;
    int histH = 400;
    int binW = cvRound((double)histW / bins[0]);
    Mat histImage = Mat::zeros(408, 560, CV_8UC3);

    Mat yHist[3]; 
    yHist[0] = bgrCalc[0].clone();
    yHist[1] = bgrCalc[1].clone();
    yHist[2] = bgrCalc[2].clone();

    normalize(bgrCalc[0], bgrCalc[0], 0, histImage.rows, NORM_MINMAX, -1, Mat());
    normalize(bgrCalc[1], bgrCalc[1], 0, histImage.rows, NORM_MINMAX, -1, Mat());
    normalize(bgrCalc[2], bgrCalc[2], 0, histImage.rows, NORM_MINMAX, -1, Mat());

    Scalar szBGR[3];
    szBGR[0] = Scalar(255,0,0);
    szBGR[1] = Scalar(0,255,0);
    szBGR[2] = Scalar(0,0,255);
    //直方图
    for(int i=1; i(i-1));
            int x2 = binW * i;
            int y2 = histH - cvRound(bgrCalc[j].at(i));
            line(histImage, Point(x1, y1), Point(x2, y2), szBGR[j], 1, LINE_4, 0);
        }
    }

    //x坐标轴
    for(int i=0; i(i, j);
            rectangle(hist2d, Point(i, j), Point(i+1, j+1), Scalar::all(binVal), -1); //Scalar::all(0)就是给每个通道都赋值0
        }
    }

    namedWindow("2D直方图", WINDOW_NORMAL);
    imshow("2D直方图", histList); //2D直方图

    namedWindow("2维灰度直方图", WINDOW_NORMAL);
    imshow("2维灰度直方图", hist2d); //2维灰度直方图

    applyColorMap(hist2d, hist2d, COLORMAP_JET);
    namedWindow("2维彩色直方图", WINDOW_NORMAL);
    imshow("2维彩色直方图", hist2d); //2维彩色直方图
}

/* 直方图均衡化 */
void PictureAlgorithm::test4()
{
    /*Mat src = imread("../x64/Debug/picture/2.jpg", IMREAD_GRAYSCALE);
    imshow("灰度图", src);

    equalizeHist(src, src);
    imshow("灰度图均衡化", src);*/

    Mat image = imread("../x64/Debug/picture/8.jpg", IMREAD_REDUCED_COLOR_2); //对BGR均衡化
    imshow("彩色图", image);

    std::vector bgrPlane;
    split(image, bgrPlane);

    equalizeHist(bgrPlane[0], bgrPlane[0]);
    equalizeHist(bgrPlane[1], bgrPlane[1]);
    equalizeHist(bgrPlane[2], bgrPlane[2]);

    Mat image1;
    merge(bgrPlane, image1);
    imshow("彩色图均衡化", image1);

    //Mat image = imread("../x64/Debug/picture/1.jpg", IMREAD_REDUCED_COLOR_2); //对hsv亮度均衡化
    //imshow("彩色图", image);

    //Mat hsv;
    //cvtColor(image, hsv, COLOR_BGR2HSV);
    //std::vector bgrPlane;
    //split(hsv, bgrPlane);
    //equalizeHist(bgrPlane[2], bgrPlane[2]);

    //Mat image1;
    //merge(bgrPlane, image1);
    //cvtColor(image1, image, COLOR_HSV2BGR);
    //imshow("彩色图均衡化", image);

    //Mat image = imread("../x64/Debug/picture/1.jpg", IMREAD_REDUCED_COLOR_2); //对yuv亮度均衡化
    //imshow("彩色图", image);

    //Mat yuv;
    //cvtColor(image, yuv, COLOR_BGR2YUV);
    //std::vector bgrPlane;
    //split(yuv, bgrPlane);
    //equalizeHist(bgrPlane[0], bgrPlane[0]);

    //Mat image1;
    //merge(bgrPlane, image1);
    //cvtColor(image1, image, COLOR_YUV2BGR);
    //imshow("彩色图均衡化", image);
}

/* 卷积 */
void PictureAlgorithm::test5()
{
    Mat image = imread("../x64/Debug/picture/4.jpg", IMREAD_REDUCED_COLOR_2);
    imshow("22", image);

    Mat meanCon;
    blur(image, meanCon, Size(3,3), Point(-1, -1)); //均值卷积
    imshow("1", meanCon);

    Mat verCon;
    blur(image, verCon, Size(1,9), Point(-1, -1)); //垂直卷积
    imshow("3", verCon);
}

/* 高斯模糊 */
void PictureAlgorithm::test6()
{
    Mat image = imread("../x64/Debug/picture/2.jpg", IMREAD_REDUCED_COLOR_2);
    imshow("1", image);

    Mat image1;
    GaussianBlur(image, image1, Size(9,9), 15); //默认sigmaX等于sigmaY
    imshow("22", image1);

    GaussianBlur(image, image1, Size(15,5), 15, 5);
    imshow("3", image1);

    GaussianBlur(image, image1, Size(0,0), 15, 5);
    imshow("4", image1);
}

/* 高斯双边模糊 */
void PictureAlgorithm::test7()
{
    //保边去噪
    Mat image = imread("../x64/Debug/picture/9.jpg", IMREAD_REDUCED_COLOR_2);
    imshow("1", image);

    Mat image1;
    bilateralFilter(image, image1, 0, 200, 10);
    imshow("22", image1);
}


/* 降采样 */
void PictureAlgorithm::test8()
{
    Mat src = imread("../x64/Debug/picture/1.jpg", IMREAD_REDUCED_COLOR_2);
    Mat enlarge, narrow, mPyr;
    imshow("1", src);

    cv::resize(src, narrow, Size(src.cols / 2, src.rows / 2), 0, 0, INTER_LINEAR);
    imshow("缩小", narrow);

    pyrDown(src, mPyr);
    imshow("降采样", mPyr);
}

/* 边缘处理得到图片轮廓 */
void PictureAlgorithm::test9()
{
    Mat image = imread("../x64/Debug/picture/8.jpg", IMREAD_REDUCED_COLOR_2);
    imshow("22", image);

    Mat meanCon;
    blur(image, meanCon, Size(3,3), Point(-1, -1)); //均值卷积(卷积之后,边缘更简单)

    Mat dst;
    Canny(meanCon, dst, 50, 100, 3, false); //边缘处理
    imshow("4", dst);

    Mat mask;
    mask.create(image.size(), image.type());
    image.copyTo(mask, dst);
    imshow("5", mask);

    //先两次降采样,再边缘处理(得到卡通画)
    Mat mask1,dst1;
    pyrDown(image, mask1);
    pyrDown(mask1, mask1);
    Canny(mask1, dst1, 50, 100, 3, false);
    namedWindow("6", WINDOW_NORMAL);
    imshow("6", dst1);
}

/* 取向量集的协方差矩阵 */
void PictureAlgorithm::test10()
{
    Mat_ samples[3];
    for (int i = 0; i < 3; i++) {
        samples[i].create(1, 3);
        samples[i](0, 0) = i*3 + 1;
        samples[i](0, 1) = i*3 + 2;
        samples[i](0, 2) = i*3 + 3;
    }
    Mat_ covMat;
    Mat_ meanMat;
    calcCovarMatrix(samples, 3, covMat, meanMat, CovarFlags::COVAR_NORMAL);

    std::string fileName = "test.txt"; 
    std::cout << "samples[0]" << samples[0] << std::endl;
    std::cout << "samples[1]" << samples[1] << std::endl;
    std::cout << "samples[2]" << samples[2] << std::endl;
    std::cout << "meanMat" << meanMat << std::endl;
    std::cout << "covMat" << covMat << std::endl;
}

/* 直角坐标和极坐标转换 */
void PictureAlgorithm::test11()
{
    //直角坐标->极坐标
    Mat x = (Mat_(3, 1) << 3, 6, 1);
    Mat y = (Mat_(3, 1) << 4, 8, 1);
    Mat magnitude, angle;
    cartToPolar(x, y, magnitude, angle);

    std::cout << "\nmagnitude: " << magnitude.t() << std::endl;
    std::cout << "\nangle: " << angle.t() * 180. / CV_PI << std::endl;

    //极坐标->直角坐标
    Mat magnitude1 = (Mat_(3, 1) << 5, 10, 1.4142135);
    Mat angle1 = (Mat_(3, 1) << 0.92740309, 0.92740309, 0.78523159);
    Mat x1, y1;
    polarToCart(magnitude1, angle1, x1, y1);

    std::cout << "\nx: " << x1.t() << std::endl;
    std::cout << "\ny: " << y1.t() << std::endl;
}

/* 检查范围和图片比较 */
void PictureAlgorithm::test12()
{
    Mat image = imread("../x64/Debug/picture/1.jpg", IMREAD_REDUCED_COLOR_2);
    Mat image2 = imread("../x64/Debug/picture/4.jpg", IMREAD_REDUCED_COLOR_2);
    bool ret = checkRange(image, true);

    Mat image3;
    cv::compare(image, image2, image3, CMP_GT); //大于
    imshow("6", image3);
}

/* 矩阵对称 */
void PictureAlgorithm::test13()
{
    float fData[25] = { 0 };
    for (int i = 0; i < 25; i++) {
        fData[i] = i+10;
    }

    float fData1[25] = { 0 };
    for (int i = 0; i < 25; i++) {
        fData1[i] = i+10;
    }
    cv::Mat m(5, 5, CV_32FC1, fData);
    cv::Mat n(5, 5, CV_32FC1, fData1);

    std::cout << m  << "\n" << std::endl;

    completeSymm(m, true);

    completeSymm(n, false);

    std::cout << m << "\n" << std::endl;
    std::cout << n << "\n" << std::endl;

    Mat image = imread("../x64/Debug/picture/17.jpg", IMREAD_REDUCED_COLOR_2); //必须是正方形图片
    completeSymm(image, false);
    imshow("6", image);
}

/* 图像增强 */
void PictureAlgorithm::test14()
{
    Mat image = imread("../x64/Debug/picture/3.jpg", IMREAD_REDUCED_COLOR_2);
    Mat image1;
    convertScaleAbs(image, image1, 1.2, 20);
    imshow("6", image);
    imshow("7", image1);

    //矩阵非0个数
    Mat image2 = imread("../x64/Debug/picture/3.jpg", IMREAD_GRAYSCALE);
    int count = countNonZero(image2); //必须是单通道
    std::cout << count << "\n" << std::endl;
}

/* 离散余弦变换和逆变换 */
void PictureAlgorithm::test15()
{
    Mat image = imread("../x64/Debug/picture/2.jpg", IMREAD_GRAYSCALE);

    Mat image1;
    image.convertTo(image1, CV_32F); 
    normalize(image1, image1, 1.0, 0, NORM_MINMAX); //先归一化
    imshow("1", image1);

    Mat image2;
    cv::dct(image1, image2, DCT_INVERSE);
    imshow("2", image2);

    Mat image3;
    cv::idct(image2, image3, DCT_INVERSE); //逆变换会丢帧
    imshow("3", image3);
}

/* 傅里叶变换和逆变换 */
void PictureAlgorithm::test16()
{
    Mat image = imread("../x64/Debug/picture/2.jpg", IMREAD_GRAYSCALE);

    Mat image1;
    image.convertTo(image1, CV_32F); 
    normalize(image1, image1, 1.0, 0, NORM_MINMAX);//先归一化

    Mat image2;
    cv::dft(image1, image2, DFT_INVERSE);
    imshow("2", image2);

    Mat image3;
    cv::idft(image2, image3, DCT_INVERSE); //逆变换会丢帧
    imshow("3", image3);
}

/* 获得矩阵的特征值和特征矢量 */
void PictureAlgorithm::test17()
{
    Mat image = imread("../x64/Debug/picture/1.jpg", IMREAD_GRAYSCALE);
    Mat image1 = imread("../x64/Debug/picture/6.jpg", IMREAD_GRAYSCALE);
    Mat dst;
    divide(image, image1, dst); //相除
    imshow("7", dst);

    Mat src = imread("../x64/Debug/picture/10.jpg", IMREAD_GRAYSCALE);
    Mat src1, dst1, dst2;
    src.convertTo(src1, CV_32FC1);
    normalize(src1, src1, 1.0, 0, NORM_MINMAX);//先归一化
    eigen(src1, dst1, dst2);
    imshow("1", dst1);

    std::cout << dst1 << "\n" << std::endl;
}

/* 指数 */
void PictureAlgorithm::test18()
{
    Mat src = imread("../x64/Debug/picture/3.jpg", IMREAD_GRAYSCALE);
    Mat src1, src2;
    src.convertTo(src1, CV_32FC1);
    exp(src1, src2);

    imshow("1", src2);
}

/* 广义矩阵乘法 */
void PictureAlgorithm::test19()
{
    RNG &rng = theRNG();
    Mat_ A(5, 10, CV_32F);
    Mat_ B(10, 5, CV_32F);
    Mat_ C = Mat::zeros(5, 5, CV_32F);

    rng.fill(A, RNG::NORMAL, 1, 100); //mean=1,stddev=100
    rng.fill(B, RNG::NORMAL, 2, 50);
    
    cv::gemm(A, B, 1, C, 0, C);

    std::cout << A << "\n" << std::endl;
    std::cout << B << "\n" << std::endl;
    std::cout << C << "\n" << std::endl;
}

/* 求矩阵的逆 */
void PictureAlgorithm::test20()
{
    float fData[25] = { 0 };
    for (int i = 0; i < 25; i++) {
        fData[i] = i+10;
    }
    cv::Mat m(5, 5, CV_32FC1, fData);

    Mat src2;
    invert(m, src2, DECOMP_SVD); //奇异值分解

    std::cout << m << "\n" << std::endl;
    std::cout << src2 << "\n" << std::endl;
}

/* 自然对数 */
void PictureAlgorithm::test21()
{
    float fData[25] = { 0 };
    for (int i = 0; i < 25; i++) {
        fData[i] = i+10;
    }
    cv::Mat m(5, 5, CV_32FC1, fData);

    Mat src1;
    log(m, src1);

    std::cout << m << "\n" << std::endl;
    std::cout << src1 << "\n" << std::endl;
}

/* 矩阵的查找表的转换 */
void PictureAlgorithm::test22()
{
    //单通道
    uchar lutData1[256];
    for (int i = 0; i<256; i++)
    {
        if(i <= 100) {
            lutData1[i] =0;
        }

        if (i > 100 && i <= 200){
            lutData1[i] = 100;
        }

        if (i > 200){
            lutData1[i] = 255;
        }
    }
  
    Mat lut(1, 256, CV_8UC1, lutData1);
    Mat src1, src3;
    Mat src = imread("../x64/Debug/picture/11.jpg", IMREAD_GRAYSCALE);
    LUT(src, lut, src1);
    imshow("1", src);
    imshow("2", src1);

    //三通道
    uchar lutData[256 * 3];
    int j = 0;
    for (int i = 0; i<256; i++) {
        if (i <= 100) {
            lutData[i * 3] = 0;
            lutData[i * 3 + 1] = 0;
            lutData[i * 3 + 2] = 0;
        }

        if (i > 100 && i <= 200) {
            lutData[i * 3] = 100;
            lutData[i * 3 + 1] = 100;
            lutData[i * 3 + 2] = 100;
        }

        if (i > 200) {
            lutData[i * 3] = 255;
            lutData[i * 3 + 1] = 255;
            lutData[i * 3 + 2] = 255;
        }
    }

    Mat lut1(1, 256, CV_8UC3, lutData);
    Mat src2 = imread("../x64/Debug/picture/11.jpg", IMREAD_REDUCED_COLOR_2);
    LUT(src2, lut1, src3);
    imshow("3", src2);
    imshow("4", src3);
}

/* 马氏距离 */
void PictureAlgorithm::test23()
{
    Mat Pt(2, 5, CV_64FC1);
    Pt.at(0, 0) = 2;
    Pt.at(1, 0) = 4;

    Pt.at(0, 1) = 2;
    Pt.at(1, 1) = 2;

    Pt.at(0, 2) = 3;
    Pt.at(1, 2) = 3;

    Pt.at(0, 3) = 4;
    Pt.at(1, 3) = 4;

    Pt.at(0, 4) = 4;
    Pt.at(1, 4) = 2;
    std::cout << Pt << std::endl;

    //计算协方差矩阵
    Mat coVar, meanVar;
    calcCovarMatrix(Pt, coVar, meanVar, COVAR_NORMAL|COVAR_COLS);
    std::cout << "Covar is:\n" << coVar << std::endl;
    std::cout << "Mean is:\n" << meanVar << std::endl;
    //计算协方差的逆
    Mat iCovar;
    invert(coVar, iCovar, DECOMP_SVD);

    Mat pt1(2, 1, CV_64FC1);
    Mat pt2(2, 1, CV_64FC1);
    pt1.at(0, 0) = 1;
    pt1.at(1, 0) = 1;
    pt2.at(0, 0) = 5;
    pt2.at(1, 0) = 5;

    double Maha1 = Mahalanobis(pt1, meanVar, iCovar);
    double Maha2 = Mahalanobis(pt2, meanVar, iCovar);
    std::cout << "Maha 距离1是:\t" << Maha1 << std::endl;
    std::cout << "Maha 距离2是:\t" << Maha2 << std::endl;
}

/* 将得到的频谱相乘 */
void PictureAlgorithm::test24()
{
    Mat image = imread("../x64/Debug/picture/2.jpg", IMREAD_GRAYSCALE);
    Mat image4 = imread("../x64/Debug/picture/5.jpg", IMREAD_GRAYSCALE);

    Mat image1;
    image.convertTo(image1, CV_32F); 

    Mat image2;
    cv::dft(image1, image2, DFT_INVERSE);
    imshow("2", image2);

    Mat image11;
    image4.convertTo(image11, CV_32F);

    Mat image22;
    cv::dft(image11, image22, DFT_INVERSE);
    imshow("1", image22);

    Mat dst;
    mulSpectrums(image2, image22, dst, DFT_COMPLEX_OUTPUT); //将得到的频谱相乘
    imshow("4", dst);

    Mat dst1;
    mulTransposed(image2, dst1, 1); //计算矩阵及其转置的乘积
    imshow("5", dst1);
}

//获得构建的主要方向
double getOrientation(std::vector &pts, Mat &img)
{
    //构建pca数据。这里做的是将轮廓点的x和y作为两个维压到data_pts中去。
    Mat data_pts = Mat(pts.size(), 2, CV_64FC1);//使用mat来保存数据,也是为了后面pca处理需要
    for (int i = 0; i < data_pts.rows; ++i) {
        data_pts.at(i, 0) = pts[i].x;
        data_pts.at(i, 1) = pts[i].y;
    }
    
    PCA pca_analysis(data_pts, Mat(), 0); //执行PCA分析
    Point pos = Point(pca_analysis.mean.at(0, 0), pca_analysis.mean.at(0, 1)); //获得最主要分量(均值),在本例中,对应的就是轮廓中点,也是图像中点
    
    std::vector eigen_vecs(2); //特征值
    std::vector eigen_val(2);   //特征值
    for (int i = 0; i < 2; ++i) {
        eigen_vecs[i] = Point2d(pca_analysis.eigenvectors.at(i, 0), pca_analysis.eigenvectors.at(i, 1));
        eigen_val[i] = pca_analysis.eigenvalues.at(i, 0); //在轮廓/图像中点绘制小圆
        circle(img, pos, 3, CV_RGB(255, 0, 255), 2);

        //计算出直线,在主要方向上绘制直线(每个特征向量乘以其特征值并转换为平均位置。有一个 0.02 的缩放系数,它只是为了确保矢量适合图像并且没有 10000 像素的长度)
        line(img, pos, pos + 0.02 * Point(eigen_vecs[0].x * eigen_val[0], eigen_vecs[0].y * eigen_val[0]), CV_RGB(255, 255, 0));
        line(img, pos, pos + 0.02 * Point(eigen_vecs[1].x * eigen_val[1], eigen_vecs[1].y * eigen_val[1]), CV_RGB(0, 255, 255));
        
        return atan2(eigen_vecs[0].y, eigen_vecs[0].x); //最终计算并返回一个最强的(即具有最大特征值)的特征向量的角度
    }
}

/* PCA获取物体主要方向(形心) */
void PictureAlgorithm::test25()
{
    Mat src = imread("../x64/Debug/picture/12.png", IMREAD_REDUCED_COLOR_2);
    imshow("输入图像", src);
    Mat gray,binary;
    cvtColor(src, gray, COLOR_BGR2GRAY);
    
    threshold(gray, binary, 150, 255, THRESH_BINARY); //阈值处理
    imshow("二值化", binary);
    
    std::vector > contours;
    std::vector hierarchy;
    findContours(binary, contours, hierarchy, RETR_LIST, CHAIN_APPROX_NONE); //寻找轮廓
    
    for (size_t i = 0; i < contours.size(); ++i) { //轮廓分析,找到工件
        double area = contourArea(contours[i]);    //计算轮廓大小
        if (area < 1e2 || 1e4< area) {             //去除过小或者过大的轮廓区域(科学计数法表示le2表示1X10的2次方)
            continue; 
        }
        drawContours(src, contours, i, Scalar(0, 0, 255), 2, 8, hierarchy, 0); //绘制轮廓
       
        double angle = getOrientation(contours[i], src); //寻找每一个轮廓的方向
        std::cout << angle << std::endl;
    }

    imshow("结果", src);
}

//把图像归一化为0-255,便于显示
Mat norm_0_255(const Mat& src)
{
    Mat dst;
    switch (src.channels()) {
    case 1:
        cv::normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
        break;
    case 3:
        cv::normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC3);
        break;
    default:
        src.copyTo(dst);
        break;
    }
    return dst;
}

//转化给定的图像为行矩阵
Mat asRowMatrix(const std::vector& src, int rtype, double alpha = 1, double beta = 0)
{
    size_t n = src.size(); //样本数量
    if (n == 0) { //如果没有样本,返回空矩阵
        return Mat();
    }
   
    size_t d = src[0].total(); //样本的维数
    Mat data(n, d, rtype);
    
    for (int i = 0; i < n; i++) { //拷贝数据
        Mat xi = data.row(i);
        if (src[i].isContinuous()) { //转化为1行,n列的格式
            src[i].reshape(1, 1).convertTo(xi, rtype, alpha, beta);
        }
        else {
            src[i].clone().reshape(1, 1).convertTo(xi, rtype, alpha, beta);
        }
    }
    return data;
}

/* PCA对数据集降维处理 */
void PictureAlgorithm::test26()
{
    std::vector db;
    db.push_back(imread("../x64/Debug/picture/13.png", IMREAD_GRAYSCALE));
    db.push_back(imread("../x64/Debug/picture/14.png", IMREAD_GRAYSCALE));

    Mat data = asRowMatrix(db, CV_32FC1); //用行中的观察结果构建一个矩阵
    int num_components = 1; //PCA算法保持5主成分分量
    PCA pca(data, Mat(), 0, num_components); //执行pca算法

    Mat mean = pca.mean.clone(); //copy pca算法结果
    Mat eigenvalues = pca.eigenvalues.clone();
    Mat eigenvectors = pca.eigenvectors.clone();

    imshow("avg", norm_0_255(mean.reshape(1, db[0].rows))); //均值脸
    imshow("pc1", norm_0_255(pca.eigenvectors.row(0)).reshape(1, db[0].rows)); //特征脸
}

/* SVD压缩图像 */
void PictureAlgorithm::test27()
{
    Mat image = imread("../x64/Debug/picture/15.jpg", IMREAD_GRAYSCALE);
    imshow("1", image);
    Mat temp(image.size(), CV_32FC1, Scalar(0));
    image.convertTo(image, CV_32FC1);

    Mat U, W, V;
    SVD::compute(image, W, U, V);//opencv得到的V与MATLAB相比已经经过转置了,要想再转置一遍可以用V=V.t();
    Mat w(image.rows, image.rows, CV_32FC1, Scalar(0));//opencv进行SVD分解后得到的奇异值W不是放入对角矩阵,而是一个列向量中,所以需要自己将其变换为对角矩阵

    double theratio = 0.1; //压缩比例--数值越小,压缩越厉害
    int len = theratio * W.rows;

    for (int i = 0; i < len; i++) {
        w.ptr(i)[i] = W.ptr(i)[0];
    }

    temp = U * w * V;
    temp.convertTo(temp, CV_8UC1);

    imshow("2", temp);
}

你可能感兴趣的:(opencv,算法,人工智能)