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

Place image on rectangle after detection in OpenCV

我目前正在开发一个 android 应用程序,用户可以在其中选择他们想要的衬衫,然后使用后置摄像头将其放在 body 之上。检测部分已完成并开始工作,下面是我到目前为止所做的代码。

nerds_thesis_clartips_OpencvClass.h //header 文件 nerds_thesis_clartips_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_thesis_clartips_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' 我应该怎么办?任何 help/ideas 将不胜感激。

通过查看您的代码:

        //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.: 关于你检测到尸体后停止,可能是崩溃了,或者你只调用了一次这个函数?最好再发一个问题,让你得到更多会员的帮助,也让其他会员更快找到答案。