Android Question Measuring Person's height With Camera

walterf25

Expert
Licensed User
Longtime User
Hi, i just had an interesting talk with a business owner and one of the questions that were asked was, Is it possible to develop an App that can measure a person's height, I've seen many apps that can be used to measure length on a surface, and even width but have never seen an App that an accurately measure a person's height.

Wanted to get someone's input on this, what do you guys think, is this possible?

I've looked into AR, as google's AR has an example to measure length and width, but i was not able to accurately measure a person's height.

Would this be possible using any other method, OpenCV, Machine Learning etc.

Has anyone came across this very same question?

Let's hear it!

Walter
 

hatzisn

Expert
Licensed User
Longtime User
Manually? For example take the picture and move two horizontal or vertical lines with your finger. Then get the height with calculations.

Edit - See also my previous post.
 
Upvote 0

JohnC

Expert
Licensed User
Longtime User
Instead of asking the person to hold an item of known size or shape, why not just ask the person what their height is ;)
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
Instead of asking the person to hold an item of known size or shape, why not just ask the person what their height is ;)
?‍♂️
 
Upvote 0

hatzisn

Expert
Licensed User
Longtime User
Instead of asking the person to hold an item of known size or shape, why not just ask the person what their height is ;)

???

In some applications like Body Mass Index - BMI for some doctors you cannot rely on what the patient thinks their height is. But then again there is no need for high tech measurement since there are the old mechanical measures.
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
For anyone who is interested I think I found a solution, may not be the best but so far it seems to work just fine.

I found this link using OpenCV and Python, I decided to give it a try since there is an Android OpenCV library wrapped by @JordiCP a big thank you to him for his contribution.

I modified the example a little bit to first take an picture of a reference Object of known size next to the object being measured, so far it looks promising, attached is a picture of me measuring the height of an iPhone X, the 25 cents coin next to it is the reference object of known size, once that quarter is found, we perform the calculations mentioned on the project and we take that as our reference calibration values, from there on any object found will be measured in reference to the known size object.

As seen in the image provided, the height being measured in this case is 5.59 inches, roughly around 0.7% error, not too bad.

Screenshot_20200831-130217.jpg

Anyone has a better idea on how to create something better or more accurate?

Walter
 
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
I found this link using OpenCV and Python, I decided to give it a try since there is an Android OpenCV library wrapped by @JordiCP a big thank you to him for his contribution.
Nice example :)

I think this method is both very simple and effective, if you can put a reference object of comparable size at the same distance of the camera.

0.7% is a good result depending on your needs. Perhaps, for further improvements (using this same method)
  • Making the reference object bigger, will decrease the per-pixel error --> ideal would be to have an object of comparable size.
  • Also work with as much resolution as possible (also to decrease pixel error)
  • If you look at the iPhone X rotated bounding rectangle, the long vertical sides show that it is slightly a trapezoid. This can be due to the fact that angle is not 90º and/or that the object is not centered in the screen, so it is seen with a bit of perspective.
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
Nice example :)

I think this method is both very simple and effective, if you can put a reference object of comparable size at the same distance of the camera.

0.7% is a good result depending on your needs. Perhaps, for further improvements (using this same method)
  • Making the reference object bigger, will decrease the per-pixel error --> ideal would be to have an object of comparable size.
  • Also work with as much resolution as possible (also to decrease pixel error)
  • If you look at the iPhone X rotated bounding rectangle, the long vertical sides show that it is slightly a trapezoid. This can be due to the fact that angle is not 90º and/or that the object is not centered in the screen, so it is seen with a bit of perspective.
Thanks for your input @JordiCP, I plan on looking for better ways of improving it, I did try with larger size objects and indeed it works a lot better and more accurate.

However for my real purpose, I tried taking a picture of the reference object right next to my Daughter, however in this case this becomes more tricky because the camera finds way more contours on a person, so it becomes difficult to detect the rectangle around a person, the known object is detected just fine but ideally it would be best to be able to subtract the background from the image and somehow superimpose a black background, what are your thoughts on this?

I am also looking at the HogDescriptor which i see you also wrapped on this OpenCV library, so that i can better detect a person, i found an example in C++ but from what I see it on the video they demonstrate on the example it detect a person but fails to detect most of the time.

this is the example i found online.

I haven't really tried to implement it, but i am guessing this would be a lot better than what i've done so far.

What are your thoughts on this?

Walter
 
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
May be wrong, but, as I see it, HogDescriptor or others can be useful to detect people among several other objects, but won't necessarily always give you an accurate bounding rectangle. --> If you know that the picture will have a person and a known reference object (i.e., you control what appears in the picture), perhaps a valid approach would be:

  • If the person has a white wall behind her, just put a couple of reference points (small coloured circle marks) in the wall, one with its center at 1m and another at 2m (or whatever)
  • Take a picture of the person vertically centering the camera between these 2 points. Then find the contours. With this, you will get:
    • The contours of the 2 reference points --> with this, you will have the Y coordinates (in pixels) of each one of the centers (in this case 1m and 2m)
    • Another outer contour (you can discard the inner ones corresponding to hands, clothes, ...), that will be the outer shape of the person.
    • If you get the top Y coordinate of that person's contour, you will have his/her relative height in pixels. By interpolating this Y with the 2 obtained before (the reference points at 1m and 2m), you'll have the real height.


Note that with this method, you don't need to take a picture of the 'zero reference point', that would be the floor.
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
May be wrong, but, as I see it, HogDescriptor or others can be useful to detect people among several other objects, but won't necessarily always give you an accurate bounding rectangle. --> If you know that the picture will have a person and a known reference object (i.e., you control what appears in the picture), perhaps a valid approach would be:

  • If the person has a white wall behind her, just put a couple of reference points (small coloured circle marks) in the wall, one with its center at 1m and another at 2m (or whatever)
  • Take a picture of the person vertically centering the camera between these 2 points. Then find the contours. With this, you will get:
    • The contours of the 2 reference points --> with this, you will have the Y coordinates (in pixels) of each one of the centers (in this case 1m and 2m)
    • Another outer contour (you can discard the inner ones corresponding to hands, clothes, ...), that will be the outer shape of the person.
    • If you get the top Y coordinate of that person's contour, you will have his/her relative height in pixels. By interpolating this Y with the 2 obtained before (the reference points at 1m and 2m), you'll have the real height.


Note that with this method, you don't need to take a picture of the 'zero reference point', that would be the floor.
Again thanks for your input, I am playing with HogDescriptor just for the hell of it, since i am not too familiar with it aside from the example i found online, do you know if I would have run any training data before I attempt to use it, at the moment, i am not able to detect any people, i don't get any errors but it is not detecting anything, any tips i could use?

My code is below:
HogDescriptor:
    Dim hog As OCVHOGDescriptor
    Dim imagen As OCVMat
    imagen.Initialize
    Dim found As OCVMatOfRect
    Dim found_filtered As OCVMatOfDouble
    found.Initialize
    found_filtered.Initialize
    mUtils.bitmapToMat(origBmp, imagen, True)
    
    hog.Initialize3
    '''hog.SVMDetector = hog.DefaultPeopleDetector
    '''hog.detectMultiScale(img, found, 0, Size(8,8), Size(32,32), 1.05, 2);
    Dim size1 As OCVSize
    Dim size2 As OCVSize
    size1.Set(Array As Double(8.0,8.0))
    size2.Set(Array As Double(30.0,30.0))
    '''hog.detectMultiScale1(imagen, found, found_filtered)
    Log("width: " & imagen.width & " --- " & "height: " & imagen.height)
    For j = 0 To 99
    hog.detectMultiScale(imagen, found, found_filtered, 0.0, size1, size2, 1.05, 2.0, True)
    Log("found.size: " & found.size)
    Dim r() As OCVRect = found.toArray
    LogColor("r.size: " & r.Length, Colors.Magenta)
    Dim crl As OCVScalar
    crl.Set(Array As Double(255,0,255))
    For i = 0 To r.Length - 1
        Dim rect As OCVRect = r(i)
        mImgProc.rectangle2(imagen, r(i).tl, r(i).br, crl)
    Next
    Sleep(10)
    Next
    Dim copy As Bitmap
    copy.InitializeMutable(imagen.width, imagen.height)
    mUtils.matToBitmap1(imagen, copy)
    FitImageToView(copy.Rotate(90), imgOriginal)

this code is based on this thread i found.

I am running the same image in a loop just to see if somehow the HogDescriptor needs to be trained or something. May not be necessary.


Walter
 
Upvote 0

MrKim

Well-Known Member
Licensed User
Longtime User
1599203488549.png


 
Upvote 0
Top