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

时间:2018-02-23 10:07:48

标签: android c++ opencv native

我目前正在开发一款Android应用程序,用户可以选择自己想要的衬衫,并使用后置摄像头将其放在身体的顶部。检测部分已完成,下面的工作和下面是我目前所做的代码。

nerds_thesis_clartips_OpencvClass.h // 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;
    }*/
}
}

但是,我收到错误:     没有匹配的会员功能来拨打&#39; at&#39; 我该怎么办?任何帮助/想法将不胜感激。

1 个答案:

答案 0 :(得分:0)

查看您的代码:

        //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。:关于你在检测到身体后停止,可能是它崩溃了,或者你刚刚调用此功能一次?最好再提出一个问题,让你能够得到更多会员和其他会员的帮助,以便更快地找到答案。