Mat到IpIImage


#include <face/face_recognition.h>

void preDeal_original_img(const std::string recognitionPath, const std::string cascadeName)
{
    std::ifstream fin;
    fin.open(recognitionPath);
    if (!fin)
    {
        std::cout << "Cannot open " + recognitionPath << std::endl;
        return;
    }

    // --Detection
    cv::CascadeClassifier cascade;
    cascade.load(cascadeName);
    if (cascade.empty())
    {
        std::cout << "Cascade path error!" << std::endl;
        return;
    }

    double scale = 1.3;
    std::vector<cv::Rect> faces;
    cv::Mat gray;

    std::string name;
    std::string camera_face = "../camera_face/";
    while (getline(fin, name)) {
        if (name.empty())
        {
            continue;
        }
        name.erase(0, name.find_first_not_of(" \t"));
        name.erase(name.find_last_not_of(" \t") + 1);

        // Read Image
        cv::Mat img = cv::imread(name);
        if (img.empty())
        {
            continue;
        }

        cv::Mat_<uchar> image;
        if (img.channels() != 1)
        {
            cvtColor(img, image, CV_BGR2GRAY);
            image.convertTo(image, CV_8UC1);
        }
        else {
            image = img;
        }


        // 改变图像
        cv::Mat smallImg(cvRound(image.rows / scale), cvRound(image.cols / scale), CV_8UC1); //cvRound对double型数据进行四舍五入
        cv::resize(image, smallImg, smallImg.size(), 0, 0, cv::INTER_LINEAR);
        cv::equalizeHist(smallImg, smallImg);                                              //equalizeHist提高图像的亮度和对比度
        // --Detection
        cascade.detectMultiScale(smallImg, faces,
            1.1, 3, 0
            /*|CV_HAAR_FIND_BIGGEST_OBJECT
            |CV_HAAR_DO_ROUGH_SEARCH*/
            | CV_HAAR_SCALE_IMAGE
            ,
            cv::Size(30, 30));
        if (faces.size() > 0)
        {
            size_t pos = name.find_last_of('\\');
            std::string filename = name.substr(pos + 1);

            if (-1 == _access(camera_face.c_str(), 0))
            {
                _mkdir(camera_face.c_str());
            }

            filename = camera_face + filename;
            std::cout << filename << std::endl;
            cv::imwrite(filename, img);
        }

    }
    fin.close();

    //处理后的图片路径名写入Path_Image.txt中
    std::string getImgPathTxt = "cd " + camera_face + " && dir /b/s/p/w *.jpg > Path_Images.txt";
    system(getImgPathTxt.c_str());
}

std::vector<std::pair<cv::Mat, std::string >> get_CropFace_And_ImgPathName(const std::string recognitionPath, const std::string cascadeName)
{
    std::vector<std::pair<cv::Mat, std::string>> cropFaceAndImgPathNames;
    std::pair<cv::Mat, std::string> cropFaceAndImgPathName;

    cv::CascadeClassifier cascade;
    cascade.load(cascadeName);
    if (cascade.empty())
    {
        std::cout << "Cascade path error!" << std::endl;
        return std::vector<std::pair<cv::Mat, std::string >>();
    }

    std::ifstream fdatabase;
    fdatabase.open(recognitionPath);
    if (!fdatabase)
    {
        std::cout << "Cannot open " + recognitionPath << std::endl;
        return std::vector<std::pair<cv::Mat, std::string >>();
    }

    double scale = 1.3;
    std::vector<cv::Rect> faces;
    cv::Mat gray;
    std::string name;

    std::cout << "[";

    while (getline(fdatabase, name)) {
        if (name.empty())
        {
            continue;
        }
        name.erase(0, name.find_first_not_of(" \t"));
        name.erase(name.find_last_not_of(" \t") + 1);

        // Read Image
        cv::Mat img = cv::imread(name);
        if (img.empty())
        {
            continue;
        }
        cv::Mat image;
        if (img.channels() != 1)
        {
            cvtColor(img, image, CV_BGR2GRAY);
            image.convertTo(image, CV_8UC1);
        }
        else {
            image = img;
        }

        // Read Opencv Detection Bbx
        cv::Mat smallImg(cvRound(image.rows / scale), cvRound(image.cols / scale), CV_8UC1); //cvRound对double型数据进行四舍五入
        cv::resize(image, smallImg, smallImg.size(), 0, 0, cv::INTER_LINEAR);
        cv::equalizeHist(smallImg, smallImg);                                              //equalizeHist提高图像的亮度和对比度
        // --Detection
        cascade.detectMultiScale(smallImg, faces,
            1.1, 3, 0
            /*|CV_HAAR_FIND_BIGGEST_OBJECT
            |CV_HAAR_DO_ROUGH_SEARCH*/
            | CV_HAAR_SCALE_IMAGE
            ,
            cv::Size(30, 30));
        for (std::vector<cv::Rect>::iterator r = faces.begin(); r != faces.end(); r++)
        {
            cv::Rect face;
            face.x = int(r->x * scale);
            face.y = int(r->y * scale);
            face.width = int(r->width * scale);
            face.height = int(r->height * scale);

            // 边界检查,左边界,上边界,右边界,下边界。
            /*face.x = face.x < 1 ? 1 : face.x;
            face.y = face.y < 1 ? 1 : face.y;
            face.width = (face.x + face.width) > image.cols ? (image.cols - face.x) : face.width;
            face.height = (face.y + face.height) > image.rows ? (image.rows - face.y) : face.height;*/

            cv::Mat cropFace;
            cropFace = img(face);
            /*cv::moveWindow("cropface", 960 - cropFace.cols / 2, 540 - cropFace.rows / 2);
            cv::imshow("cropface", cropFace);
            cv::waitKey(100);
            cv::destroyWindow("cropface");*/

            cropFaceAndImgPathName = make_pair(cropFace, name);  //cropFaceAndImgPathName = std::pair<cv::Mat, std::string>(cropFace, name);

            cropFaceAndImgPathNames.push_back(cropFaceAndImgPathName);

            std::cout << '.';
        }

    }

    fdatabase.close();

    std::cout << "]" << std::endl;

    return cropFaceAndImgPathNames;
}

bool matchFace(cv::Mat detectFace, cv::Mat dbFace)
{
    IplImage* srcImg = cvCloneImage(&(IplImage)detectFace);
    IplImage* dstImg = cvCloneImage(&(IplImage)dbFace);

    IplImage* src;
    IplImage* dst;

    if (srcImg->nChannels != 1)
    {
        src = cvCreateImage(cvSize(srcImg->width, srcImg->height), srcImg->depth, 1);
        cvCvtColor(srcImg, src, CV_BGR2GRAY);
    }

    if (dstImg->nChannels != 1)
    {
        dst = cvCreateImage(cvSize(dstImg->width, dstImg->height), dstImg->depth, 1);
        cvCvtColor(dstImg, dst, CV_BGR2GRAY);
    }

    int histogramBins = 256;
    float histogramRange1[2] = { 0, 255 };
    float* histogramRange[1] = { &histogramRange1[0] };
    CvHistogram* Histogram1 = cvCreateHist(1, &histogramBins, CV_HIST_ARRAY, histogramRange);
    CvHistogram* Histogram2 = cvCreateHist(1, &histogramBins, CV_HIST_ARRAY, histogramRange);

    cvCalcHist(&src, Histogram1);
    cvCalcHist(&dst, Histogram2);

    cvNormalizeHist(Histogram1, 1);
    cvNormalizeHist(Histogram2, 1);


    // CV_COMP_CHISQR,CV_COMP_BHATTACHARYYA这两种都可以用来做直方图的比较,值越小,说明图形越相似  
    //printf("CV_COMP_CHISQR : %.4f\n", cvCompareHist(Histogram1, Histogram2, CV_COMP_CHISQR));
    //printf("CV_COMP_BHATTACHARYYA : %.4f\n", cvCompareHist(Histogram1, Histogram2, CV_COMP_BHATTACHARYYA));  


    // CV_COMP_CORREL, CV_COMP_INTERSECT这两种直方图的比较,值越大,说明图形越相似  
    //printf("CV_COMP_CORREL : %.4f\n", cvCompareHist(Histogram1, Histogram2, CV_COMP_CORREL));  
    //printf("CV_COMP_INTERSECT : %.4f\n", cvCompareHist(Histogram1, Histogram2, CV_COMP_INTERSECT));
    double simility = cvCompareHist(Histogram1, Histogram2, CV_COMP_CHISQR);

    if (simility > 0.5)
    {
        return false;
    }

    return true;
}

void face_recognition(std::string recognitionPath, const std::string cascadeName)
{
    bool isPreDeal = false;
    if (isPreDeal)              //是否进行预处理
    {
        preDeal_original_img(recognitionPath, cascadeName);
        recognitionPath = "../camera_face/";
    }

    //获取数据库中人脸图像
    std::string face_Database = "../face_database/Path_Images.txt";
    std::vector<std::pair<cv::Mat, std::string>> cropFaceAndImgPathNames;
    std::cout << "开始数据库中人脸数据的读取..." << std::endl;
    cropFaceAndImgPathNames = get_CropFace_And_ImgPathName(face_Database, cascadeName);
    std::cout << "结束数据库中人脸数据的读取。" << std::endl;

    //开始人脸匹配
    std::ifstream frecognition;
    frecognition.open(recognitionPath);
    if (!frecognition)
    {
        std::cout << "Images path Error!" << std::endl;
        return;
    }

    cv::CascadeClassifier cascade;
    cascade.load(cascadeName);
    if (cascade.empty())
    {
        std::cout << "Cascade path error!" << std::endl;
        return;
    }

    double scale = 1.3;
    std::vector<cv::Rect> faces;
    cv::Mat gray;
    std::string name;

    bool isExist = false;   //数据库中是否存在该匹配文件

    while (getline(frecognition, name)) {
        if (name.empty())
        {
            continue;
        }
        name.erase(0, name.find_first_not_of(" \t"));
        name.erase(name.find_last_not_of(" \t") + 1);

        // Read Image
        cv::Mat img = cv::imread(name);
        cv::Mat image;
        if (img.channels() != 1)
        {
            cvtColor(img, image, CV_BGR2GRAY);
            image.convertTo(image, CV_8UC1);
        }
        else {
            image = img;
        }

        // Read Opencv Detection Bbx
        cv::Mat smallImg(cvRound(image.rows / scale), cvRound(image.cols / scale), CV_8UC1); //cvRound对double型数据进行四舍五入
        cv::resize(image, smallImg, smallImg.size(), 0, 0, cv::INTER_LINEAR);
        cv::equalizeHist(smallImg, smallImg);                                              //equalizeHist提高图像的亮度和对比度
        // --Detection
        cascade.detectMultiScale(smallImg, faces,
            1.1, 3, 0
            /*|CV_HAAR_FIND_BIGGEST_OBJECT
            |CV_HAAR_DO_ROUGH_SEARCH*/
            | CV_HAAR_SCALE_IMAGE
            ,
            cv::Size(30, 30));
        for (std::vector<cv::Rect>::iterator r = faces.begin(); r != faces.end(); r++)
        {
            cv::Rect face;
            face.x = int(r->x * scale);
            face.y = int(r->y * scale);
            face.width = int(r->width * scale);
            face.height = int(r->height * scale);

            cv::Mat detectFace = img(face);

            for (std::vector<std::pair<cv::Mat, std::string>>::iterator dbFace = cropFaceAndImgPathNames.begin(); dbFace != cropFaceAndImgPathNames.end(); dbFace++)
            {
                std::pair<cv::Mat, std::string> dbFaceImg = *dbFace;
                bool isMatch = matchFace(detectFace, dbFaceImg.first);
                if (isMatch) {
                    std::cout << name + " Matching " + dbFaceImg.second + " successful!" << std::endl;
                    cv::imshow("detectFace", detectFace);
                    cv::imshow("databaseFace", dbFaceImg.first);
                    cv::waitKey(200);
                    cv::destroyWindow("detectFace");
                    cv::destroyWindow("databaseFace");
                    isExist = true;
                }
            }

        }
    }

    if (!isExist)
    {
        std::cout << name + " Matching failed!" << std::endl;
    }

    frecognition.close();
}


192行,193行出现错误,请问这种错误应该怎么改啊

```严重性    代码    说明    项目    文件    行    禁止显示状态
错误(活动)    E0312    不存在用户定义的从 "cv::Mat""IplImage" 的适当转换    ConsoleApplication1    D:\Clion\demo\ConsoleApplication1\face_recognition.cpp    192    


换成 IplImage* srcImg = detectFace.clone()看下,应该是后面的那个强制转换失败了,或者 IplImage* srcImg = cvCloneImage((IplImage*)detectFace);