Ask Your Question
2

Multi-person poses' detection using OpenCV + OpenPose

asked 2018-04-09 09:30:23 -0600

Sergey Netyagin gravatar image

updated 2018-04-10 05:49:42 -0600

Hello, dear colleagiues!

I recently started studying computer vision. I'm very interested this direction. Now I'm studying the recognition of human poses, and I'm trying to remake some examples in C # to experiment further in Unity.

However, I can not find documentation or examples of how I could improve my code anywhere to find the poses of all people in the image. Could you tell me how I should change my code so that I can recognize the poses for all people in the image?

CODE FRAGMENT:

private void RecognizePose( Mat image, Mat output_image, List<point> points, float[] data ) {

for( int i = 0; i < BODY_PARTS_MPI.Count; i++ ) {

    output_image.get( i, 0, data );

    Mat heat_map = new Mat ( 1, data.Length, CvType.CV_32FC1 );

    heat_map.put( 0, 0, data );

    //Originally, we try to find all the local maximums. To simplify a sample
    //we just find a global one. However only a single pose at the same time
    //could be detected this way.
    Core.MinMaxLocResult result = Core.minMaxLoc( heat_map );

    heat_map.Dispose();

    double x = (

        (image.cols() * 
        (result.maxLoc.x % matrix_output_columns)) / 
        matrix_output_columns
    );

    double y = (

        (image.rows() * 
        (result.maxLoc.x / matrix_output_rows)) / 
        matrix_output_rows
    );

    if( result.maxVal > 0.1d ) points.Add( new Point( x, y ) );
    else points.Add( null );
}

}

Line "Core.MinMaxLocResult result = Core.minMaxLoc( heat_map );" and next processing gets us only single person's pose. And comment for this line says the same. But how can I get the all local maximumns and detect all poses?

With best regards and best wishes, Sergey Netyagin

edit retag flag offensive close merge delete

Comments

does this (java?) code even work for a single person ?

i'm having some doubts, if output_image.get( i, 0, data ); is retrieving the right thing, imho, there should be a output_image=output_image.reshape(1,19); before trying to access it's data

berak gravatar imageberak ( 2018-04-09 12:06:32 -0600 )edit
  • you'll HAVE TO read the paper
  • it needs the original, linevec.prototxt,not opencv's shortened one (it does not have access to the PAF's)
  • i made an attempt at it lately, but there are still bugs
berak gravatar imageberak ( 2018-04-10 06:20:07 -0600 )edit
1

Yes..!! It works perfectly fine for a single person.

The code is available at this link: https://github.com/opencv/opencv/blob...

The step to reproduce is as follows: python3 openpose.py --input=COCO_val2014_000000000589.jpg --proto=openpose_pose_coco.prototxt --model=pose_iter_440000.caffemodel --dataset=COCO

The data is available at:

--> COCO_val2014_000000000589.jpg

https://github.com/CMU-Perceptual-Com...

--> openpose_pose_coco.prototxt

https://github.com/opencv/opencv_extr...

--> pose_iter_440000.caffemodel

http://posefs1.perception.cs.cmu.edu/...

Gajjar_Mihir gravatar imageGajjar_Mihir ( 2018-04-11 06:16:08 -0600 )edit

i know, i know.

i was only questioning your java version of it. (are you sure, you got the heatmap extraction right ?)

berak gravatar imageberak ( 2018-04-11 06:43:47 -0600 )edit
2

I am trying to implement it on android (java). The code works on ubuntu with opencv 3.4.1 but I am getting error on android with opencv 3.4.1. I have explained the error here: https://github.com/opencv/opencv/issu...

I tried the code on some images till now. It does fail sometimes.

Any help would be appreciated.

Gajjar_Mihir gravatar imageGajjar_Mihir ( 2018-04-11 06:54:51 -0600 )edit

could you add that part of the code to your question ?

(btw, your github repo is no more available)

berak gravatar imageberak ( 2018-04-11 06:58:36 -0600 )edit

Should I upload the Android project on my Github repo or should I paste the code here?

I think uploading would be a better option because the entire code would be visible there with indentation.

Gajjar_Mihir gravatar imageGajjar_Mihir ( 2018-04-11 08:31:49 -0600 )edit

a few lines with the result parsing here AND your whole code on github, maybe ?

berak gravatar imageberak ( 2018-04-11 08:58:44 -0600 )edit
1


int frameWidth = mat1.width();
int frameHeight = mat1.height();
Log.d("DEBUG",frameHeight + " " + frameWidth + " " + mat1);
Mat inp = Dnn.blobFromImage(mat1, 1, new Size(368, 368), new Scalar(0,0,0),false,false);
Log.d("See Hererere", inp.height() + " " + inp.width() + " " + inp.channels());
net.setInput(inp);
Mat out = net.forward();
Log.d("OUTPUT", out + "");

I am getting error in net.forward()

I have uploaded the entire code on github.

Gajjar_Mihir gravatar imageGajjar_Mihir ( 2018-04-19 05:54:50 -0600 )edit

github link ?

maybe you can try this one in the meantime

berak gravatar imageberak ( 2018-04-19 06:07:55 -0600 )edit

The android project is about 700mb. Can we upload that on github?

Gajjar_Mihir gravatar imageGajjar_Mihir ( 2018-04-19 06:19:57 -0600 )edit

no, you can't.

put your main java file somewhere. above code isn't all too helpful

"I am getting error in net.forward()" -- do we have to guess the error ?

berak gravatar imageberak ( 2018-04-19 06:29:40 -0600 )edit
1

I am extremely sorry. I have uploaded the main java file here . I have uploaded a file named error.txt also which contains the error.

error(): OpenCV(3.4.1) Error: Assertion failed (inputs[0]->size[1] % blobs[0].size[1] == 0) in virtual void cv::dnn::ConvolutionLayerImpl::forward(std::vector<cv::mat*>&, std::vector<cv::mat>&, std::vector<cv::mat>&), file /build/master_pack-android/opencv/modules/dnn/src/layers/convolution_layer.cpp, line 962

Gajjar_Mihir gravatar imageGajjar_Mihir ( 2018-04-19 06:59:13 -0600 )edit

@Gajjar_Mihir ,

  • don't be sorry, it just takes longer this way ....
  • your image is CV_8UC4, while the convolution expects 3 channels only (that's the error)
  • 1.0/255 , not 1 here

  • you need to reshape the output to 19 rows here

  • float, not double here

  • again, take a look here, it worked ! (also somewhat easier, without the string lookups)

berak gravatar imageberak ( 2018-04-19 07:48:20 -0600 )edit

I think the point float, not double here does not point to the correct line. I tried with the previous two changes but the image remains CV_8UC4 only and the same error persists.

And the code openpose.java sample. Should I try it with android or with normal java compiler?

Gajjar_Mihir gravatar imageGajjar_Mihir ( 2018-04-20 07:00:24 -0600 )edit

indeed, l. 153 instead.

you need to cvtColor() your image, COLOR_ARGB2BGR

berak gravatar imageberak ( 2018-04-20 07:07:37 -0600 )edit

And also for lines 157 and 158 ?

I cannot use Float at line 153. It shows that out.get(0,i) is a double[] and hence I cannot use MatofFloat there.

Gajjar_Mihir gravatar imageGajjar_Mihir ( 2018-04-20 07:13:29 -0600 )edit

no, it does not matter there. (your're puttiing x,y in an integer Point anyway later)

berak gravatar imageberak ( 2018-04-20 07:18:37 -0600 )edit

line 153 should probably be:

Mat heatmap = out.row(i)

get(i,j) only returns a single pixel (as an array of doubles) , so that's wrong anyway.

did not see it before, sorry.

berak gravatar imageberak ( 2018-04-20 07:22:53 -0600 )edit

I am not able to find COLOR_ARGB2BGR also.

Can we reduce the number of channels using mat1 = mat1.reshape(3) ?

Gajjar_Mihir gravatar imageGajjar_Mihir ( 2018-04-20 07:28:01 -0600 )edit

no you can't reshape that, you have to throw away the (unused) A channel. it's probably BGRA2BGR then, but idk. (not using android) try to see, if the image looks right, afterwards.

berak gravatar imageberak ( 2018-04-20 07:44:22 -0600 )edit

Okay so I think there is some progress. Now I am getting the points but only the x coordinates. All the y coordinates are zero. And also I am getting no error.

Gajjar_Mihir gravatar imageGajjar_Mihir ( 2018-04-20 08:01:25 -0600 )edit

yea, use heatmap.reshape(1,46) instead, so you have a 46x46 image for minmaxloc. that will also have proper x,y coords

berak gravatar imageberak ( 2018-04-20 08:10:27 -0600 )edit

Yes. Now it works perfectly fine. I tried it out on several images and it works fine. Thank you very much for your help. I really appreciate it. Is there any way to improve the predictions. Like should I have a better quality image or something like that?

Gajjar_Mihir gravatar imageGajjar_Mihir ( 2018-04-20 08:43:09 -0600 )edit

ah, cool. how long does it take ?

berak gravatar imageberak ( 2018-04-20 08:53:24 -0600 )edit
1

It takes about 40 seconds on my Xiaomi Redmi Note 4 with the following specifications: 1. Snapdragon 625 processor 2. 4GB RAM 3. CPU: Octa-core 2.0 GHz Cortex-A53 4. GPU: Adreno 506

Gajjar_Mihir gravatar imageGajjar_Mihir ( 2018-04-21 01:57:39 -0600 )edit

I am just getting the points. Is there any way to show these points in the image like draw the skeleton overlapping the image?

Gajjar_Mihir gravatar imageGajjar_Mihir ( 2018-04-21 02:11:11 -0600 )edit

just draw lines connecting them ? look at the c++ / python / java samples

berak gravatar imageberak ( 2018-04-21 02:14:05 -0600 )edit

Yeah the lines can be drawn but the coordinates which I am getting do not correspond to the pixels of the original image. So how can the coordinates be overlapped on the image?

And are you also getting the same time about 40 seconds or is there anyway to optimize the time?

Gajjar_Mihir gravatar imageGajjar_Mihir ( 2018-04-21 02:20:13 -0600 )edit

i get like 30 seconds on a laptop (there is another , tf trained network, that can run in 3 seconds, but it is less accurate)

"but the coordinates which I am getting do not correspond to the pixels of the original image." -- how so ? did you miss the scaling from heatmap to img coords ? again, look at the existing examples, it's a solved problem.

berak gravatar imageberak ( 2018-04-21 02:26:03 -0600 )edit

Yes I haven't scaled the heatmap. I tried to find it in the example openpose.java. How should I convert them so that they correspond to the pixels of the original image?

Gajjar_Mihir gravatar imageGajjar_Mihir ( 2018-04-21 04:11:13 -0600 )edit

Yes. It works perfectly fine. Thank you for your help. Again I really appreciate your help :) :)

Gajjar_Mihir gravatar imageGajjar_Mihir ( 2018-04-23 07:19:00 -0600 )edit

I am just curious to know how opencv does this.

I am also trying to use the .pb file provided by ildoonet on Github to get the predictions. I was able to get the output of the last node but I still dont know how to process it to get the coordinates(predictions of the joints).

Does opencv use this .pb file or it does something else?

Gajjar_Mihir gravatar imageGajjar_Mihir ( 2018-04-23 07:24:03 -0600 )edit

again, look at the java example, and toggle the comments for that

berak gravatar imageberak ( 2018-04-23 07:36:59 -0600 )edit

ohh ok. So is there any model which gives better predictions than this (pose_iter_440000.caffemodel) ?

Gajjar_Mihir gravatar imageGajjar_Mihir ( 2018-04-23 07:43:37 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2018-07-16 15:02:48 -0600

Roma gravatar image

OpenPose example in python working with multi-person (3 files) : https://gist.github.com/buff4life123/...

run "openpose_multiple_person"

@berak @Gajjar_Mihir @Sergey Netyagin

edit flag offensive delete link more

Comments

the scripts may have some not used lines of code (so you can remove that lines)

Roma gravatar imageRoma ( 2018-07-16 15:08:21 -0600 )edit

@Roma, cool !

berak gravatar imageberak ( 2018-07-17 05:04:45 -0600 )edit

Question Tools

3 followers

Stats

Asked: 2018-04-09 09:29:15 -0600

Seen: 2,507 times

Last updated: Jul 16 '18