代码之家  ›  专栏  ›  技术社区  ›  Abegail

在OpenCV中检测后,将图像放置在矩形上

  •  1
  • Abegail  · 技术社区  · 6 年前

    我目前正在开发一个android应用程序,用户可以选择自己想要的衬衫,并使用后置摄像头将其放在身体上方。检测部分已经完成,下面是我到目前为止所做的代码。

    nerds\u thesis\u clartips\u OpencvClass。h类 //nerds\u thesis\u clartips\u OpencvClass的头文件。cpp公司

    #include <jni.h>
    #include <opencv2/opencv.hpp>
    #include <iostream>
    #include <vector>
    /* Header for class nerds_thesis_clartips_OpencvClass */
    
    using namespace cv;
    using namespace std;
    
    #ifndef _Included_nerds_thesis_clartips_OpencvClass
    #define _Included_nerds_thesis_clartips_OpencvClass
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     nerds_thesis_clartips_OpencvClass
     * Method:    humanDetection
     * Signature: (J)V
     */
    
     void detectHuman(Mat& frame);
    
    JNIEXPORT void JNICALL Java_nerds_thesis_clartips_OpencvClass_humanDetection
      (JNIEnv *, jclass, jlong);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    

    nerds\u thesis\u clartips\u OpencvClass。cpp公司 //C++文件

    #include "nerds_thesis_clartips_OpencvClass.h"
    
    JNIEXPORT void JNICALL Java_nerds_thesis_clartips_OpencvClass_humanDetection (JNIEnv *, jclass, jlong addrRgba){
    Mat& frame = *(Mat*)addrRgba;
    
    detectHuman(frame);
    }
    
    void detectHuman(Mat& frame){
    // assign xml file to a variable
    String human_cascade_name = "/storage/emulated/0/data/haarcascade_upperbody.xml";
    CascadeClassifier human_cascade;
    
    // load xml file
    if(!human_cascade.load( human_cascade_name ) ) { printf("--(!)Error loading\n"); return; };
    
    std::vector<Rect> humans;
    Mat frame_gray;
    Mat original;
    frame.copyTo(original);
    
    //convert input to grayscale
    cvtColor( frame, frame_gray, CV_BGR2GRAY );
    //increase image contrast
    equalizeHist( frame_gray, frame_gray);
    
    //Detect Human
    human_cascade.detectMultiScale( frame_gray, humans, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(100, 100) );
    
    //for (int i=0; i<humans.size(); i++)
        //rectangle(frame, Point(humans[i].x, humans[i].y), Point(humans[i].x+humans[i].width, humans[i].y+humans[i].height), Scalar(0,255,0));
    
    Mat imageMask = imread("C:/Users/Requinala/AndroidStudioProjects/CLARTIPS/app/src/main/res/drawable/bluevelvet.png", 1);
    
    // Draw the mask over all rectangles
    for (size_t i = 0; i < humans.size(); i++){
    
        Rect r = humans[i];
    
        Mat humanROI = frame_gray( humans[i] ); //image of the upper body
    
        int h_temp = humans[i].height;    // storing original height
        int x = humans[i].x;
        int y = humans[i].y - h_temp*(-0.6); // y is increased by 0.6*h
        int w = humans[i].width;
        int h = h_temp; // height detected
    
        rectangle(frame,Point (x,y),Point(x + w,y +h),Scalar(255,0,255),1,4,0);
    
        /*int xx =0, yy =0;
        // Just iterate in face region pixel by pixel
        for(int x = humans[i].x; x < humans[i].x+humans[i].width; x++){
            for (int y = humans[i].y; y < humans[i].y+humans[i].height; y++){
                //Copy Mask to Original image  If the 0 chan
                //Proper condition is over all color channels
                //if (imageMask.at(xx,yy)[0] < 10){
                     // Copy to original image on (y,x) places  the pixel of xx,yy mask
                     humanROI.at(y,x)[0] = imageMask.at(xx,yy)[0];
                     humanROI.at(y,x)[1] = imageMask.at(xx,yy)[1];
                     humanROI.at(y,x)[2] = imageMask.at(xx,yy)[2];
                //}
                // Iterate in mask x
                xx =xx+1;
            }
            // iterate next row of imageMask
            xx = 0;
            yy =yy+1;
        }*/
    }
    }
    

    但是,我遇到了一些错误: 没有匹配的成员函数用于调用“at” 我该怎么办?如有任何帮助/想法,将不胜感激。

    1 回复  |  直到 6 年前
        1
  •  0
  •   api55    6 年前

    通过查看您的代码:

            //if (imageMask.at(xx,yy)[0] < 10){
                 // Copy to original image on (y,x) places  the pixel of xx,yy mask
                 humanROI.at(y,x)[0] = imageMask.at(xx,yy)[0];
                 humanROI.at(y,x)[1] = imageMask.at(xx,yy)[1];
                 humanROI.at(y,x)[2] = imageMask.at(xx,yy)[2];
            //}
    

    很容易发现问题。缺少模板规范。

    您可以将其更改为以下内容:

            //if (imageMask.at(xx,yy)[0] < 10){
                 // Copy to original image on (y,x) places  the pixel of xx,yy mask
                 humanROI.at<uchar>(y,x)[0] = imageMask.at<uchar>(xx,yy)[0];
                 humanROI.at<uchar>(y,x)[1] = imageMask.at<uchar>(xx,yy)[1];
                 humanROI.at<uchar>(y,x)[2] = imageMask.at<uchar>(xx,yy)[2];
            //}
    

    甚至更好:

            //if (imageMask.at(xx,yy)[0] < 10){
                 // Copy to original image on (y,x) places  the pixel of xx,yy mask
                 humanROI.at<Vec3b>(y,x) = imageMask.at<Vec3b>(xx,yy);
            //}
    

    这应该可以解决编译错误,但是 humanROI 在灰度中,您可以执行以下操作:

    Mat humanColorROI;
    cvtColor( humanROI, humanColorROI, CV_GRAY2BGR );
    

    获取3通道灰色图像。这样应该可以。

    P、 S:关于你检测到尸体后的停车,可能是因为它撞车了,或者你只调用了一次这个函数?最好再问一个问题,让你从更多的成员那里得到帮助,让其他成员更快地找到答案。