Last updated on July 8, 2021.
Measuring the size of an object (or objects) in an image has been a heavily requested tutorial on the PyImageSearch blog for some time now — and it feels great to get this post online and share it with you.
Today’s post is the second in a three part series on measuring the size of objects in an image and computing the distances between them.
Last week, we learned an important technique: how reliably order a set of rotated bounding box coordinates in a top-left, top-right, bottom-right, and bottom-left arrangement.
Today we are going to utilize this technique to aid us in computing the size of objects in an image. Be sure to read the entire post to see how it’s done!
- Update July 2021: Added section on how to improve object size measurement accuracy by performing a proper camera calibration with a checkerboard.
Measuring the size of objects in an image with OpenCV
Measuring the size of objects in an image is similar to computing the distance from our camera to an object — in both cases, we need to define a ratio that measures the number of pixels per a given metric.
I call this the “pixels per metric” ratio, which I have more formally defined in the following section.
The “pixels per metric” ratio
In order to determine the size of an object in an image, we first need to perform a “calibration” (not to be confused with intrinsic/extrinsic calibration) using a reference object. Our reference object should have two important properties:
- Property #1: We should know the dimensions of this object (in terms of width or height) in a measurable unit (such as millimeters, inches, etc.).
- Property #2: We should be able to easily find this reference object in an image, either based on the placement of the object (such as the reference object always being placed in the top-left corner of an image) or via appearances (like being a distinctive color or shape, unique and different from all other objects in the image). In either case, our reference should should be uniquely identifiable in some manner.
In this example, we’ll be using the United States quarter as our reference object and throughout all examples, ensure it is always the left-most object in our image:
By guaranteeing the quarter is the left-most object, we can sort our object contours from left-to-right, grab the quarter (which will always be the first contour in the sorted list), and use it to define our pixels_per_metric, which we define as:
pixels_per_metric = object_width / know_width
A US quarter has a known_width of 0.955 inches. Now, suppose that our object_width (measured in pixels) is computed be 150 pixels wide (based on its associated bounding box).
The pixels_per_metric is therefore:
pixels_per_metric = 150px / 0.955in = 157px
Thus implying there are approximately 157 pixels per every 0.955 inches in our image. Using this ratio, we can compute the size of objects in an image.
Measuring the size of objects with computer vision
Now that we understand the “pixels per metric” ratio, we can implement the Python driver script used to measure the size of objects in an image.
Open up a new file, name it object_size.py
, and insert the following code:
# import the necessary packages from scipy.spatial import distance as dist from imutils import perspective from imutils import contours import numpy as np import argparse import imutils import cv2 def midpoint(ptA, ptB): return ((ptA[0] + ptB[0]) * 0.5, (ptA[1] + ptB[1]) * 0.5) # construct the argument parse and parse the arguments ap = argparse.ArgumentParser() ap.add_argument("-i", "--image", required=True, help="path to the input image") ap.add_argument("-w", "--width", type=float, required=True, help="width of the left-most object in the image (in inches)") args = vars(ap.parse_args())
Lines 2-8 import our required Python packages. We’ll be making heavy use of the imutils package in this example, so if you don’t have it installed, make sure you install it before proceeding:
$ pip install imutils
Otherwise, if you do have imutils
installed, ensure you have the latest version, which is 0.3.6
at the time of this writing:
$ pip install --upgrade imutils
Lines 10 and 11 defines a helper method called midpoint
, which as the name suggests, is used to compute the midpoint between two sets of (x, y)-coordinates.
We then parse our command line arguments on Lines 14-19. We require two arguments, --image
, which is the path to our input image containing the objects we want to measure, and --width
, which is the width (in inches) of our reference object, presumed to be the left-most object in our --image
.
We can now load our image and preprocess it:
# load the image, convert it to grayscale, and blur it slightly image = cv2.imread(args["image"]) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) gray = cv2.GaussianBlur(gray, (7, 7), 0) # perform edge detection, then perform a dilation + erosion to # close gaps in between object edges edged = cv2.Canny(gray, 50, 100) edged = cv2.dilate(edged, None, iterations=1) edged = cv2.erode(edged, None, iterations=1) # find contours in the edge map cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours(cnts) # sort the contours from left-to-right and initialize the # 'pixels per metric' calibration variable (cnts, _) = contours.sort_contours(cnts) pixelsPerMetric = None
Lines 22-24 load our image from disk, convert it to grayscale, and then smooth it using a Gaussian filter. We then perform edge detection along with a dilation + erosion to close any gaps in between edges in the edge map (Lines 28-30).
Lines 33-35 find contours (i.e., the outlines) that correspond to the objects in our edge map.
These contours are then sorted from left-to-right (allowing us to extract our reference object) on Line 39. We also initialize our pixelsPerMetric
value on Line 40.
The next step is to examine each of the contours:
# loop over the contours individually for c in cnts: # if the contour is not sufficiently large, ignore it if cv2.contourArea(c) < 100: continue # compute the rotated bounding box of the contour orig = image.copy() box = cv2.minAreaRect(c) box = cv2.cv.BoxPoints(box) if imutils.is_cv2() else cv2.boxPoints(box) box = np.array(box, dtype="int") # order the points in the contour such that they appear # in top-left, top-right, bottom-right, and bottom-left # order, then draw the outline of the rotated bounding # box box = perspective.order_points(box) cv2.drawContours(orig, [box.astype("int")], -1, (0, 255, 0), 2) # loop over the original points and draw them for (x, y) in box: cv2.circle(orig, (int(x), int(y)), 5, (0, 0, 255), -1)
On Line 43 we start looping over each of the individual contours. If the contour is not sufficiently large, we discard the region, presuming it to be noise left over from the edge detection process (Lines 45 and 46).
Provided that the contour region is large enough, we compute the rotated bounding box of the image on Lines 50-52, taking special care to use the cv2.cv.BoxPoints
function for OpenCV 2.4 and the cv2.boxPoints
method for OpenCV 3.
We then arrange our rotated bounding box
coordinates in top-left, top-right, bottom-right, and bottom-left order, as discussed in last week’s blog post (Line 58).
Lastly, Lines 59-63 draw the outline of the object in green, followed by drawing the vertices of the bounding box rectangle in as small, red circles.
Now that we have our bounding box ordered, we can compute a series of midpoints:
# unpack the ordered bounding box, then compute the midpoint # between the top-left and top-right coordinates, followed by # the midpoint between bottom-left and bottom-right coordinates (tl, tr, br, bl) = box (tltrX, tltrY) = midpoint(tl, tr) (blbrX, blbrY) = midpoint(bl, br) # compute the midpoint between the top-left and top-right points, # followed by the midpoint between the top-righ and bottom-right (tlblX, tlblY) = midpoint(tl, bl) (trbrX, trbrY) = midpoint(tr, br) # draw the midpoints on the image cv2.circle(orig, (int(tltrX), int(tltrY)), 5, (255, 0, 0), -1) cv2.circle(orig, (int(blbrX), int(blbrY)), 5, (255, 0, 0), -1) cv2.circle(orig, (int(tlblX), int(tlblY)), 5, (255, 0, 0), -1) cv2.circle(orig, (int(trbrX), int(trbrY)), 5, (255, 0, 0), -1) # draw lines between the midpoints cv2.line(orig, (int(tltrX), int(tltrY)), (int(blbrX), int(blbrY)), (255, 0, 255), 2) cv2.line(orig, (int(tlblX), int(tlblY)), (int(trbrX), int(trbrY)), (255, 0, 255), 2)
Lines 68-70 unpacks our ordered bounding box, then computes the midpoint between the top-left and top-right points, followed by the midpoint between the bottom-right points.
We’ll also compute the midpoints between the top-left + bottom-left and top-right + bottom-right, respectively (Lines 74 and 75).
Lines 78-81 draw the blue midpoints on our image
, followed by connecting the midpoints with purple lines.
Next, we need to initialize our pixelsPerMetric
variable by investigating our reference object:
# compute the Euclidean distance between the midpoints dA = dist.euclidean((tltrX, tltrY), (blbrX, blbrY)) dB = dist.euclidean((tlblX, tlblY), (trbrX, trbrY)) # if the pixels per metric has not been initialized, then # compute it as the ratio of pixels to supplied metric # (in this case, inches) if pixelsPerMetric is None: pixelsPerMetric = dB / args["width"]
First, we compute the Euclidean distance between the our sets of midpoints (Lines 90 and 91). The dA
variable will contain the height distance (in pixels) while dB
will hold our width distance.
We then make a check on Line 96 to see if our pixelsPerMetric
variable has been initialized, and if it hasn’t, we divide dB
by our supplied --width
, thus giving us our (approximate) pixels per inch.
Now that our pixelsPerMetric
variable has been defined, we can measure the size of objects in an image:
# compute the size of the object dimA = dA / pixelsPerMetric dimB = dB / pixelsPerMetric # draw the object sizes on the image cv2.putText(orig, "{:.1f}in".format(dimA), (int(tltrX - 15), int(tltrY - 10)), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (255, 255, 255), 2) cv2.putText(orig, "{:.1f}in".format(dimB), (int(trbrX + 10), int(trbrY)), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (255, 255, 255), 2) # show the output image cv2.imshow("Image", orig) cv2.waitKey(0)
Lines 100 and 101 compute the dimensions of the object (in inches) by dividing the respective Euclidean distances by the pixelsPerMetric
value (see the “Pixels Per Metric” section above for more information on why this ratio works).
Lines 104-109 draw the dimensions of the object on our image
, while Lines 112 and 113 display the output results.
Object size measuring results
To test our object_size.py
script, just issue the following command:
$ python object_size.py --image images/example_01.png --width 0.955
Your output should look something like the following:
As you can see, we have successfully computed the size of each object in an our image — our business card is correctly reported as 3.5in x 2in. Similarly, our nickel is accurately described as 0.8in x 0.8in.
However, not all our results are perfect.
The Game Boy cartridges are reported as having slightly different dimensions (even though they are the same size). The height of both quarters are also off by 0.1in.
So why is this? How come the object measurements are not 100% accurate?
The reason is two-fold:
- First, I hastily took this photo with my iPhone. The angle is most certainly not a perfect 90-degree angle “looking down” (like a birds-eye-view) at the objects. Without a perfect 90-degree view (or as close to it as possible), the dimensions of the objects can appear distorted.
- Second, I did not calibrate my iPhone using the intrinsic and extrinsic parameters of the camera. Without determining these parameters, photos can be prone to radial and tangential lens distortion. Performing an extra calibration step to find these parameters can “un-distort” our image and lead to a better object size approximation (but I’ll leave the discussion of distortion correction as a topic of a future blog post).
In the meantime, strive to obtain as close to a 90-degree viewing angle as possible when taking photos of your objects — this will help increase the accuracy of your object size estimation.
That said, let’s look at a second example of measuring object size, this time measuring the dimensions of pills:
$ python object_size.py --image images/example_02.png --width 0.955
Nearly 50% of all 20,000+ prescription pills in the United States are round and/or white, thus if we can filter pills based on their measurements, we stand a better chance at accurately identification the medication.
Finally, we have a final example, this time using a 3.5in x 2in business card to measure the size of two vinyl EPs and an envelope:
$ python object_size.py --image images/example_03.png --width 3.5
Again, the results aren’t quite perfect, but this is due to (1) the viewing angle and (2) lens distortion, as mentioned above.
Improving object size measurement accuracy with a proper camera calibration
Before we can measure the size of an object in an image, we first need to calibrate our system. In this post, we used a simple “pixels per metric” technique.
However, better accuracy can be obtained by performing a proper camera calibration by computing the extrinsic and intrinsic parameters:
- Extrinsic parameters are rotation and translation matrices used to convert something from the world frame to the camera frame
- Intrinsic parameters are the internal camera parameters, such as the focal length, to convert that information into a pixel
Specifically, we are interested in the intrinsic parameters. But how do we go about obtaining them?
The most common way is to perform a checkerboard camera calibration using OpenCV. Doing so will remove radial distortion and tangential distortion, both of which impact the output image, and therefore the output measurement of objects in the image.
Here are some resources to help you get started with camera calibration:
- Understanding Lens Distortion
- Camera Calibration using OpenCV
- Camera Calibration (official OpenCV documentation)
What's next? I recommend PyImageSearch University.
30+ total classes • 39h 44m video • Last updated: 12/2021
★★★★★ 4.84 (128 Ratings) • 3,000+ Students Enrolled
I strongly believe that if you had the right teacher you could master computer vision and deep learning.
Do you think learning computer vision and deep learning has to be time-consuming, overwhelming, and complicated? Or has to involve complex mathematics and equations? Or requires a degree in computer science?
That’s not the case.
All you need to master computer vision and deep learning is for someone to explain things to you in simple, intuitive terms. And that’s exactly what I do. My mission is to change education and how complex Artificial Intelligence topics are taught.
If you're serious about learning computer vision, your next stop should be PyImageSearch University, the most comprehensive computer vision, deep learning, and OpenCV course online today. Here you’ll learn how to successfully and confidently apply computer vision to your work, research, and projects. Join me in computer vision mastery.
Inside PyImageSearch University you'll find:
- ✓ 30+ courses on essential computer vision, deep learning, and OpenCV topics
- ✓ 30+ Certificates of Completion
- ✓ 39h 44m on-demand video
- ✓ Brand new courses released every month, ensuring you can keep up with state-of-the-art techniques
- ✓ Pre-configured Jupyter Notebooks in Google Colab
- ✓ Run all code examples in your web browser — works on Windows, macOS, and Linux (no dev environment configuration required!)
- ✓ Access to centralized code repos for all 500+ tutorials on PyImageSearch
- ✓ Easy one-click downloads for code, datasets, pre-trained models, etc.
- ✓ Access on mobile, laptop, desktop, etc.
Summary
In this blog post, we learned how to measure the size of objects in an image using Python and OpenCV.
Just like in our tutorial on measuring the distance from a camera to an object, we need to determine our “pixels per metric” ratio, which describes the number of pixels that can “fit” into a given number of inches, millimeters, meters, etc.
To compute this ratio, we need a reference object with two important properties:
- Property #1: The reference object should have known dimensions (such as width or height) in terms of a measurable unit (inches, millimeters, etc.).
- Property #2: The reference object should be easy to find, either in terms of location of the object or in its appearance.
Provided that both of these properties can be met, you can utilize your reference object to calibrate your pixels_per_metric variable, and from there, compute the size of other objects in an image.
In our next blog post, we’ll take this example a step further and learn how to compute the distance between objects in an image.
Be sure to signup for the PyImageSearch Newsletter using the form below to be notified when the next blog post goes live — you won’t want to miss it!
Download the Source Code and FREE 17-page Resource Guide
Enter your email address below to get a .zip of the code and a FREE 17-page Resource Guide on Computer Vision, OpenCV, and Deep Learning. Inside you'll find my hand-picked tutorials, books, courses, and libraries to help you master CV and DL!
Nice write-up as always Adrian but you have missed mentioning directly the prerequisite that all of the objects to be measured be co-planar with the reference object even though you did mention that the camera must be at as near as possible 90 degrees to that plane.
To do size and or distance calculations without a reference object you need a) the lens and focus information and b) two or more images of the same scene from different angles so as to use parallax calculations.
Exactly. In a future blog post, I’ll detailing how to calibrate your cameras to obtain these parameters and thus undistort the image.
Steve, Calibration can be done by taking a top view image and a image of your original camera position, after which you can find a homography matrix by which you wrap perspective the side view image to top view perspective.To find the homography matrix you will need to find similar points in both the top view reference and input image of different plane, which can be done by finding the sift point followed by a matcher.
You can look up to Adrian’s blog on making panoramic images for reference.
Only problem I see is to find the pixels per metric ratio value by giving an width value of the ref image, compensating for the camera distance from the image. Is there any way to solve the camera distance problem in an automated fashion?
Maybe 4 square marks in the corners of image cold be useful. The camera is well calibrated if aspect ratio of all marks is the same.
we can all do with a lesson on how to calibrate your camera. Please Adrian!
Hi, I’m working with cameras that have wide angle lenses, I’m trying to find a way to calibrate the image to a chessboard grid in order to transform the image to flat front. that way, I can manipulate the image from there without the lens distortion messing up further analysis. I’d appreciate some advice, or even a blog post on the topic.
I will try to do some more advanced calibration tutorials in the future but I’m not sure when/if that will be. Thank you for the suggestion though 🙂
THANKYOU SIR!
can i help you back? like giving my prove of sucess testing your program?
Hi ,is it possible to measure the length and width of the potholes from the image .
Yes, but I would suggest you use something like Mask R-CNN or U-Net to help you automatically segment the potholes.
I think there is a mistake. Instead of 157 pixels per 0.955 inch it should be 157 pixels per inch.
Is it possible to find the volume of any object by finding the length and width from top and from side to find height from 2 different pictures?
Hi Adrian,
Did you ever end up creating this tutorial? I am very interested.
I have not. I hope to do so in the future but I’m not sure if/when that may be.
Adrian, thank you for this brilliant piece.
I have a question. Can this method be used to calculate an objected dimensions in 3D?
Thank you
I would recommend a proper camera calibration via the intrinsic/extrinsic parameters for 3D.
The problem is how to find the focal length as the pothole will be inclined to the camera (i.e) not at 90 degree.
@Gadget Steve @Adrian Rosebrock .. I want to measure the height of a person from a mobile image. Will it work if i find the homography matrix between few points in real world and corresponding points in image. Then apply that matrix to calculate image points representing humans. Or is there a better way.
Hi,
It is a really helpful article..Thanks for it.
I am currently working on identifying human body and then get the length, width and circumference of the body parts from top to bottom.
I have been able to identify the human body but getting is the measurement is an issue.
Can you please help.
Regards,
So if I understand your question correctly, your goal is to (1) detect the body, (2) extract each body part, and then (3) measure each body part? If so, you should do some research on skeletal models for the body, and perhaps even utilizing a stereo camera to help in the segmentation of each body part.
Hello Adrian,
I am currently learning the fundamentals of JavaScript and noticed that you are using python for Measuring size of objects in an image with OpenCV.
Do you teach/ cover this topic in your 17-day crash course?
Secondly, will I be able to follow the tutorials and practice with basic JavaScript knowledge.
Thank you for this great tutorial!
You are welcome!
1. Yes, I teach OpenCV + Python in the 17-day crash course.
2. As long as you have basic programming experience you will be fine when working through the 17-day course.
Wonderful, thank you very much. I think, I can apply this method to measure cells on microscope images. I already have the pixel ratio in EXIF from microscope, so I’ll declare it as a constant. Maybe you’ll suggest something more optimal for round and ellipsoid objects like cells? I think I should find the smallest and the largest diameter. After this I can find the excentricity.
In that case, you might want to compute the minimum enclosing circle or the minimum enclosing ellipse, then compute your ratios based on that. Also, you might want to look into ImageJ which is heavily used for microscopic images — I even did some work for the National Cancer Institute developing plugins for ImageJ.
Thank you. I use it with CellProfiler, but I often need to develop some new functions. So I use the scipy most of the time for image analysis. Now I want to try the opencv. Thanks again for your blog. Useful tutorials.
SciPy is definitely quite useful, but I think you’ll find that OpenCV makes it even easier, once you get the hang of it 🙂
Great Article Adrian!!
Thanks Ankit!
hi its really helpful and very cleared explained
Thank you for this post. I’m working on this problem and i found a solution for measuring objects using the focale distance. Obviously this can only work in smartphone api so i’ve been learning java to perform it and i think i’m not far from a good result. The real problem is that we need a camera with a motorised focale.
This may be considered to be a bit “off the wall” but I have 3 table tennis balls (known size) positioned at the interface between the ceiling and the wall of a room. If I have an image that shows all the balls am I correct in thinking that I can compute the distance between the balls and also the distance from the camera to each of the balls? I appreciate that lens distortion may have some impact but I’m not interested in that here as I only want to obtain an approx. room size. Assuming that the ceiling is level I would like to expand this idea to include adjacent walls and floors i.e. to generate a 3D CAD model of the room.
Yes, you are correct in your thinking. If you can segment the 3 balls from your image and you know their size, you can absolutely use this technique to compute the distance between them (I cover how to do this in next weeks blog post). You’ll also have to perform a calibration for the distance from ball to camera, but again, that’s easily doable.
Nice! Thank you for this post, it is always a pleasure to read through your tutorials and learn something new. Alternatively to this method, if you are interested in calculating the area of an object instead of retrieving its dimensions, there is a handy contourArea function in openCV! So once the contours are defined, you can easily calculate the area of each contour enclosure in pixels (1 line of code) and convert to appropriate dimensions via a reference object area. This is especially useful for the blob-like objects I am working with which have poorly defined dimensions.
Nice tip Kyle, thanks for sharing!
Hi. Thats a really nice post. I recently started programming, but i wanted to adapt this programm a bit. How can i change it that way, that my referenceobject is detectet by color?
I hope you can help me 😀
Please excuse my english, i am no native.
To detect an object based on color, I would start with this blog post. I also cover object detection inside Practical Python and OpenCV.
Hi there Adrian, awesome site.
I cannot import imutils and scipy modules.
I think this happens because the comand “sudo pip install imutils” installs it at the route “/usr/local/lib/python2.7/dist-packages” instead of “site-packages” because i can see it exploring the directories but i dont really know if this is correct or no.
I tried to install the modules outside the virtual environment and inside it, previously entering the commands “source ~./profiles” and “workon cv”.
Iam working in a raspbian jessie fresh install on a raspberry pi 3 and i followed your new openCV 3 installation tutorial without any error.
Please let me know how could i change the imutils/scipy installation directory or what other error i am committing.
Thanks in advance.
The reason you are getting this error is because you’re using
sudo
andpip
to install imutils and SciPy into the system install of Python. Instead, you should be installing them into the virtual environment:Thanks for the reply, it seens that the command pip install imutils/SciPy in the cv environment now works after a reboot.
Thank you so much for your great effort..
I have a question, Is it possible to measure the size of an object without the reference object in place.
Is it possible ..?
You need to perform some sort of camera calibration. That can be done offline before the script is deployed (provided you’re using the same camera sensors) or you can include the reference object in the image. In either case, the system must be calibrated first.
I want to extract the largest contour.
I am actually calculating size of a box, however there is another perfect contour inside the box.
So it detects both the squares. And I only want the outside one.
What should I do ?
You simply need to find the contour with the largest area:
c = max(cnts, key=cv2.contourArea)
thank you so muchhhh !
how to specify area where we need to have contour?
Hi. Thanks for this really nice post.
I recently started programming with python, but i wanted to adapt this programm a bit to my situation.
I have a set of images that represent vehicles and I want to classify them in groups based on vehicle height.
How can I do this knowing that I don’t have this reference object in place?
Thanks in advance.
At some point, you need to calibrate your camera. You can do this “offline” before you take photos of your vehicles (such as computing the reference object focal length and then removing the reference object). But at some point the camera has to be calibrated.
Hi Adrian,
Thank you so much for the post! It’s really interesting. Any advices for measuring the size of an object in real time?
You can use this same approach to measure the size of objects in real-time. Just wrap the around a method to access a video stream, such as this one.
Hi Adrian, thanks for the advice and this tutorial. I managed to use this tutorial to calibrate my object tracking project.
Actually, the computer vision bundle helped me to improve my programming skills. And I want to take pyimagesearch gurus course but my problem is that I do not have a good programming background, so it might take me some time.
No problem at all Themba, I’m happy that myself/the PyImageSearch community was able to help on your journey 🙂
Hi Adrian, I have been experimenting with different images and different objects within the image. I noticed that sometimes it does not detect some object, so to make it detect the object I varied the GaussainBlur() values from (7,7) to (11,11). However, still when I do that it does not detect all the object in the image.
So my question is how can I ensure that I detect all of the objects with the image ?
As you noted, detecting all objects in your image is highly dependent on (1) the image, (2) the contents of the image, and (3) your lighting conditions/environment. It’s hard to say which (or even all 3) is contributing to the issue here. All I can say is that you should continue to play with the parameters — but also keep in mind that for certain objects, you won’t be able to detect them using basic image processing techniques. Some objects require machine learning and/or object detection.
Hello Adrian,
First of all my sincere respect for what you’re doing.
I’m totally new at this and just started to work on measuring 3D-objects very recently.
My ultimate goal is to be able to get X, Y and Z dimension from a picture taken by a RPi V2-type camera, but the first issue to overcome is how to calibrate the camera.
I think the correct procedure would be to take several pictures from an object with known dimensions on different distances and count pixels to find the ratio formula, correct?
Any other suggestions?
3D is an entirely different world (no pun intended). I honestly don’t have much experience in 3D, my main area of expertise focuses on image search engines and image classification (and even lately, deep learning). Essentially, you would need to create a 3D model of your object from 2D images. And at that point, you’ll be doing much more complex camera calibration anyway, which would lead to better accuracy.
Hi Adrian, I request you to make tutorial on how to use calibration parameters to find distance of object ? I am struggling lot with that. I have calibration parameters but I am struggling to use that. Eagerly waiting for reply
Thanks in advance !!
Tanaji
Thanks for the suggestion, Tanaji. I’m not sure when I’ll cover that topic but I’ll try to.
Which IDE is Best to try this code
I personally like either Sublime Text 2 or the PyCharm.
wonderful post ! Explained well
Infact I’m working on a project which detects the dimensions of our dress using camera .
This helps a lot
thanks
I really find your post interesting!
I am doing a project where there is a conveyor on which boxes( cuboid shape) moves There is a 3d camera mounted on top to recognize these boxes and further we need to determine the dimensions and pose of the boxes.
I have been studying and researching a lot on these topics and what algorithms to choose and how to proceed.To be brief i am unable to proceed next.
My task has the following constraints:
1) There should be no database of models created from which one can perform feature matching to detect objects.
The algorithm used for object detection should directly detect the object and provide its pose.
2) The shape of the object is always a cuboid/box shaped. The edges of the box might not be necessarily sharp. It can have rounded edges also. But the object to detected is always box shaped
3) Also my camera would be mounted in an inclined angle( not parallel to the object)
Can i use Opencv for this task. If yes, how do i proceed??
Hey Ramanan, this sounds like a pretty neat project, although I don’t think it’s a great idea to constrain yourself from feature-based approaches. All that said, I personally don’t do much work in 3D and stereo vision, so I’m unfortunately not the right person to ask regarding this project. Best of luck!
Hi Adrian this post is very helpful
I want to put an “if” to display a “yes”, if the object has the size I want
what should I do?
have a nice day 😉
After Line 11 I would do something like:
Where the “…” signifies the remaining parameters to the function.
I def need help on combining several of these projects from pyimagesearch.com. Like skin finder, object detector, measuring, ect. Can you or anyone help me to get a project I’m trying to work on started and working starting ASAP.. Please…. Anyone.
i was wondering if Can i use this code to work together with my webcam?
-Have a nice day!!
Sure, absolutely. Simply read a frame from your camera sensor and process the frame as I do in this blog post. Here is an example of using your webcam. You can also find more detailed tutorials inside Practical Python and OpenCV.
Can someone please tell me how can i extract those measured value and put it in a txt file?
You can use simple file operations to write the measurements to file. I would suggest using using this tutorial to help you understand the basics of file operations.
Hey Adrian,
Thank you so much for this great post!
I was having a problem while installing scipy on Rpi 3. I am trying to install it into the virtual environment, however, that last thing that shows on the window “Runing setup.py bdist_wheel for scipy … /” and hangs there forever.
What can I do to install scipy… I would greatly appreciate your help!
Thanks!
It’s not “hanging” — it’s actually installing. It takes awhile to install SciPy on the Raspberry Pi 3. If I recall correctly, it took approximately 45-60 minutes to install the last time I did it.
Thanks for the reply, it was eventually installed after waiting for a while!
i want to measure object by millimeters !!
That is totally doable with this code. Just change the command line argument to be your known width in millimeters then update the
cv2.putText
call. The exact same algorithm can still be used.Hi Adrian,
Do you think is possible to get an approximate of the circumference/Shape of an object if we have 2 or 3 pictures from the object?
Yes, once you know the number of pixels per measuring metric you can compute the minimum bounding circle via
cv2.minEnclosingCircle
. This will give you the radius of the object which you can then use to derive the circumference.Hi Adrian! I’ve been a silent reader of your blogs! Personally, you have helped me a lot especially that I am working on a project now. I just want to know how to do this in real time? Like measuring objects in a video?
It is totally possible to measure the size of objects in a video stream, just wrap this code in a loop that continuously polls frames from a camera sensor. This blog post will help you get started. I also provide more examples of working with video streams inside Practical Python and OpenCV.
Firstly, thank you very much for your guidance! You are amazing! Could you please guide how to make your code work in real time?
I can’t provide 1-on-1 guidance or write the code for you, but I do highly recommend you read this post where I demonstrate how to access video streams. From there you can combine the two tutorials.
Hello,
Thanks for the nice guide. I have a problem. I Have a camera. I want to take a photo from the camera and mark out an area on it using mouse. Then i want to calculate the area within the marked area. Can you please guide me how do I do it?
Regards
If you want to use mouse events, please refer to this blog post. This post will show you how to use mouse events to capture your click and marking.
Thanks Adrian for the reply, it was a nice read.
What I need to do is draw a freeform area, not any specific geometric shapes like squares/rectangles/circles, and finally calculate the area within.
Regards
Max
In that case, I would modify the script to maintain a list of (x, y)-coordinates that you click. You can then loop over them and draw them with
cv2.line
. There is also a polygon drawing function in OpenCV but I can’t remember the name of it off the top of my head. You can look it up in the OpenCV docs.after executing the code I’m getting error of image required.. even after mentioning the path and Is there a need to import argparse if yes then plz do tell how to install it.
Regards
It sounds like you are having problems with the command line arguments. I would suggest you read this tutorial before continuing.
sir, may I ask how to get the angle of things while your program about the measuring of objects? before that, personally I’m very grateful of your code and thanks to you
You can use the
cv2.minAreaRect
function to obtain the angle of a rotated rectangle that encapsulates the object.Hi Adrian,
Hope you had a wonderful Christmas!
I have been following your tutorials, and I have learned quite a lot of things from implementing these projects.
Now I have a question, would it be possible to determine the size of the object with the following conditions:
1.Without a reference object
2.We know the FOV
3.We know the distance – readings from a sensor.
Would you be able to give me some directions?
Thank you,
GK
If you don’t have a reference object you would need to calibrate your camera and determine the intrinsic camera parameters first.
Thank you Adrian.
Would you be able to give me some specifics on the parameters?
Here’s what I thought I’d do:
I know the distance, real time measurements from a sensor.
I know the F of the camera.
I know the area occupied by the object in the image.
Based on this, following your tutorial on finding the distance between the object and the camera, would it not be possible to find the size of the object?
Note: the object is in the same plane as the entire image. There are no other objects in between or in the background.
It’s not exactly that simple. I don’t have any tutorials on this topic at the moment, but I’ll certainly add it to my queue and try to cover it in the future. I can’t think of any good existing Python tutorials off the top of my head, but I know this MATLAB tutorial would be a good start for you to understand the basic principles.
Thank you Adrian, for the suggestion. I have one more question.
Would it be possible to measure the size of the object, if I have a reference object with known size and distance, but in separate images?
So, here’s what I’m looking at:
I know the size, and the distance to a known object – separate images (following your tutorial, 3 images).
I know the focal length and the actual distance from camera to the target object – from a sensor, I’m able to find the real-time distance.
This looks doable to me, I’m just kind of confused :-/ Would you be able to throw some light on this issue? Thank you 🙂
If the images were captured using the same (calibrated) camera sensor, then yes, you could still compute the object size.
Hi!
I have implemented your example and modified it a little to work with live video. Now I’m trying to get measurements on objects’ volume using only the webcam. Can you point me in some direction? Thanks!
P.S.: Adrian, your content rocks! Thanks for the effort and congrats on the approaches. Always easy to learn from you.
What type of object are you working with? Normally computing the volume would require depth information, in which case I would recommend using a stereo/depth camera instead.
Hey, Adrian. Thanks for the attention.
I’m working mainly with boxes and packages. It’s for a logistics project. It’s a challenge and I’m restrained to webcams, though I can use other commonly available material. Of course I’m expecting not-so-refined measures.
Cheers!
Personally, I don’t think you’re going to get a decent measure of volume without using 2 cameras. If you can setup two webcams you could essentially create a stereo-vision environment by calibrating them and obtaining an approximate depth map.
Hi
I’m working on a similar project. Did you make any progress on finding the volume?
Hi Marcos,
For implementing it for live video, can you explain how you did it? Do you have any link where you have posted the code?
Thanks
I have another thought on the approach. If I crop the image to keep the coin part, and then use the labelling method to find its size in pixels. Finally, using the pixels and the known dimensions I would find the pixels per metric. Would that be a right approach?
Yes, if you can manually label the ROI and use the ROI to compute the dimensions this is essentially equivalent to teh calibration step.
I have one template image where i have fixed size rectangle which contain some information. Now, i want to search that exact fixed size rectangle from query image then perform cropping. Query image may be in different DPI/resolution format.How can i deal with this issue? Is this article help me? Please suggest some idea for solving it.
Thanks in advance.
If your query image is a different resolution I would suggest always resizing the query to a fixed resolution and then applying the multi-scale template matching technique proposed in this blog post.
Hi Adrian, I am new to computer vision and as the other commenters said many times I am absolutely grateful with the help you’re providing the community.
I noticed your comment regarding the need to aim squarely at the target to obtain a precise measurement. In my case by design my target will be up to 2 degree off. Is there a way to compensate for this?
What I’m trying to do is aim a laser at a ruler placed a few feet out and capture the laser position (e.g. aiming at the 128mm mark). I’m not sure if the better approach is:
1) to write code to detect this laser line and use ocr to interpret where its aiming
or 2) use the technique presented in this post and find a way to offset the 1-2 degree distortion. I know the ruler total length, could I measure distance to the left and right sides of the ruler to derive its angle and then use this info to compensate when measuring the target object length (e.g. from the ruler zero mark to the laser line)?
I’m shooting for 1 or 2 mm accuracy. Thanks in advance for pointing me in the right direction
The method in this blog post requires only simple camera calibration based on the output image. For your level of accuracy I would suggest instead computing the intrinsic properties of the camera and doing a much more accurate calibration. I don’t have a tutorial on this at the moment, but I will try to do one in the future. In the meantime, take a look at this excellent resource on intrinsic camera properties.
Hi Adrian!
Thank you so much for this post- it’s really great!
For some reason, this script doesn’t animate for me like yours does. I just see the coin’s dimensions and none of the dimensions of the other items. I’m running an Ubuntu VM on Mac.
What would you recommend I do?
I’m not sure what you mean by “animate” as I created a GIF file to demonstrate the animation. Click on the active window and press any key to advance the detections. The call to
cv2.waitKey
pauses execution.Oh! Thank you so much, Adrian! It all works now.
Hi Adrian! Thank you so much for this useful post
when i run this program tell me this error
Traceback (most recent call last):
…
from scipy.spatial import distance as dist
ImportError: No module named scipy.spatial
also i installed scipy
i’m waiting for your help
It sounds like you might have forgotten to install NumPy and SciPy:
$ pip install numpy scipy
hello adrian.. it’s work very well in mine…
but if i wanna change the source image to webcam, what steps should i do so it’s well work in my raspi 3? i try change the source but it’s always failed.. thanks for the knowledges
Please follow this tutorial on accessing your Raspberry Pi camera.
Hello Adrian;
I want to detect seperate bottles from an image of 5 bottles and process on it that is detect neck and shoulder of bottle and find the centre point of the two and check whether the liquid is filled upto that point. Can you help?
Hey Prateek — I think it would be easier to offer help in this situation if you had an example image of what you’re working with.
hello Adrian, i want to save the measuring sizes and send it to arduino in order to compare it with a data base, is it possible and how ?
Can you help?
My problem is not counting this point is please help me!
Thank you
If these points are not neatly together, and in what way we can resolve this problem.
i am try your script but after run. like this ?
usage: object_size.py [-h] -i IMAGE -w WIDTH
object_size.py: error: argument -i/–image is required
You need to supply the command line arguments to the script. You can read more about command line arguments here.
i am trying to run the code but its throwing the error.. i just want to know that what i have to write in place of -i and –image in order to run the entire code because its throwing an error
Code:
ap.add_argument(“-i”, “–image”,
Please read up on command line arguments before continuing. Knowledge of command line arguments will fix your issue.
Hi Adrian,
I have a problem py [-h] -i IMAGE -w WIDTH
meas.py: error: the following arguments are required: -i/–image, -w/–width
im using python 3 and opencv3
Please read up on command line arguments. You are forgetting to supply command line arguments to the script.
Hello Adrian;
Thanks for amazing blog post, thanks in advance for this great toturial..
I want to save the result in one image and result show me measurement for all objects in one image
Plz help me
Regards
You want to save the resulting image to disk? If so, just use
cv2.imwrite
.No, I know this
But I want to draw all the lines for all objects and saved it in a single image..?? How i can do?
Thanks in advance for reply
Hi adrean;
I have a question
Why we used dilate and erode algorithm??
What the work of these two algorithms?
If ypu can quide me to these two algorithm
Thanks in advance fo reply
Best regards
The dilation and erosion helps close any gaps between edges in the edge map.
Thank you for reply dear dr. Adrian
Hi, can this method (or similar) be used to measure the length of a curved object? Specifically an animal that is not perfectly straight? I need to find a way to measure the nose to tail length, but the animal may be bent in the middle.
I’m not familiar on the science/literature of measuring the length of animals, but I think it would have to be an approximation to the length, especially if the animal is free and moving. Otherwise, if you know the contour of the body, then you might be able to apply splines to determine the length, but that’s something I have not done.
thanks for your sharing! I get the same cases with Rich, I wanna measure the length of a curved object but with a static condition (not moving), have you try it yet? I get some trouble with the bent part of the object.
Hi Adrian Rosebrock !!!
I’m really impressed with this article !!!
I just need to know how to change the code for giving the image and width directly in the code instead of giving it in command prompt .
Eventhough it is a simple question to you please guide me because i’m a beginner here
Thanks in advance
There are a number of ways to do this, but if you want the easiest, foolproof way to do, change Line 20 (after the command line arguments are parsed) to be:
args["width"] = YOUR_WIDTH
Otherwise, delete the command line argument parsing code and hardcode the values into separate variables.
Hi Adrian Rosebrock
Thank u so Much for this Article
Can u give me the code for automating it by taking photograph from webcam and process it instead of giving it in command line…
Sorry, I do not write code for you. I am happy to help point you in the right direction and provide these blog posts, but again, I cannot write the code for you. If you need help working with your webcam consider referring to one of my many tutorials here on PyImageSearch or working through Practical Python and OpenCV.
hello , i just want ask to question regarding the pixel measurement,, suppose i have an image with pixel dimension of 1366×768 .. the center of image consist of a red bounding rectangle, is it possible for opencv to get the pixel dimension of the rectangle ? in pixels also like 500px x 400px ?? thank you sir ..
Yes. Simply detect the red bounding rectangle compute its bounding box.
chi, how can i get pixel measurement of object in an image instead of inches?
The pixel measurement is used to derive the inches. You already have the pixel measurement. Specifically, Lines 90 and 91 compute the distance in pixels.
Thanx for the nice work Andrian, I want to measure particle size distribution for particles on a fast moving conveyor belt. I have tested your method and it seems quite slow for the application, can you point me in the right direction?
The issue here will be running your application in real-time. The algorithm this method uses is actually quite fast, but you might be running into issues with I/O latency. I would also make sure that the camera you are using can read frames at a frame rate high enough to ensure you can (accurately) measure your objects. To reduce I/O latency, take a look at this tutorial.
Hi Adrian,
Awesome post – everything that I’ve read on your blob has been very clear and useful! Super impressed 🙂
I’m working on a simple application that attempts to measure the height and width of a perfect rectangle in the image with a reference object. However, the perspective distortion in the images isn’t constrained (meaning no perfect perpendicular picture like in this example). Additionally, the reference object is very small compared to the rest of the image – meaning I can’t warp the rectangle based on the perspective transform of the reference. Any thoughts on how to approach this problem?
Thanks!
This certainly makes the project more challenging. It sounds like you need a more advanced camera calibration, such as computing the intrinsic and extrinsic parameters.
Hello Sir,
Can you pitch and suggest some idea to measure the hand size from the hand pic. The reference of the hand size is given in the picture what i mean “https://drive.google.com/file/d/0B7u-f_qlWl0jTVpvMHJWWk5wRzQ/view?usp=sharing” Please help me with that
If you’re trying to measure the size of the hand you can use this tutorial. You find the points along the hand you want to measure and then use the triangle similarity we covered here. The Euclidean distance between the points will give you distance in pixels. Then apply the triangle similarity to determine the distance in real-world metrics.
Hallo Adrian,
I am working on identifying human body and then measure the arm span and Length. I use the camera of car. I dont have a refrence in Image. Can i do that with instrinsic and extrinsic calibration. Is it maybe possible with “Multi view Geometry”. please help me with that.
Thanks
Hi Nana — you would need to use camera calibration and ideally multiple cameras to do this project. I am not an expert on 3D/stereo vision so I would suggest using this tutorial in the OpenCV docs to help you get started.
Hi
I`m not sure my result right or not, so how can I find the material that you used in your blog ?
Another confused point, why I can`t pip install `pyimagesearch` appeared in your another blog, are you write this moduel ? How can I install it, I want to redo what you’ve done of your blog.
thanks for you attention.
Please use the “Downloads” section of this tutorial to download a .zip of the code. Inside you’ll find the “pyimagesearch” module.
Hello Adrian,
Awesome post – everything that I’ve read on your blog has been very clear and useful! Super impressed, how can I run it on windows or ubuntu? because I tried all the ways, please help me
Hi Yassin — this code will work on Ubuntu and Windows. Use the “Downloads” section, download the code, and then execute. If you are running into an error feel free to share.
Hello Adrian,
First of all, I would like to thank for your posts. Recently I have jumped into the computer vision domain.
Please let me how to implement the below points
1) I need to set a unique ID automatically for each object in an image.
say example – Figure 1 has 6 objects (Including reference object). ID should automatically generate for all six objects (Example:ob1,ob2…ob6)
2) get all the object’s height and width with object ID into a text file
Example:
ob1 0.9 1.0
ob2 0.5 0.5
.
.
.
also, Correct me if my question is wrong or it has any logic mistake.
Thanks in advance.
I would suggest applying an object tracking algorithm. The simplest would be “centroid tracking”. Compute the centroid of all objects in consecutive frames. Then compute their Euclidean distances. Centroids with the smallest Euclidean distance belong to the same object. Your logic is correct, but you need to implement centroid tracking.
Hello, is there a way using OpenCV to obtain measurements for different human body areas like: neck, person height, belly, etc… We are looking into this for a wellness and nutrition follow up. Thx
It can, but not easily. You could also get wildly inaccurate results depending on how good (or poor) your human body segmentation algorithm is. Typically the best results would come from stereo vision/depth cameras to aid in the segmentation. However, this is not something I have ever tried.
Hi Adrian, is it possible to use this tutorial to calculate the dimensions of the bounding box for the “Real-time object detection with deep learning and OpenCV” tutorial you’ve done recently? I am thinking of using the dimensions of the bounding box to determine the distance a person is away from the camera, since the further you stand away from the camera, the smaller you are and hence the smaller the bounding box. Thanks!
Provided you perform the triangle similarity to obtain a rough calibration for the camera, yes, you can combine this method with the deep learning-based object detector to obtain an approximation to the distance.
Would i need a stereo camera for that? I was just thinking of a way to measure the dimensions of the bounding boxes. With the dimensions, i would then use the values to do a simple command where the robot stops moving when the size of the bounding box reaches > a certain value. Thanks!
Stereo and 3D cameras would undoubtedly given you better segmentations and approximations to depth, thereby giving you more accurate measurements. You can still do an approximation using a simple 2D camera though, provided that your detections are accurate enough.
hi
I just downloaded the code and trying in my pc the problem I faced is that the object is placed only one image not traversing all the object in image
Hi Pawan — can you elaborate on your comment? I’m not sure what your exact question is.
in the tutorial as I see the measurement of objects in rotating through each object in the image but when i tried with the downloaded code with the same image the hight width box is still on one object image it is not measuring the other object size. ( )
Hi Adrian, first of all a pleasure to be in your page, well I have a doubt I hope you can help me clarify I do not understand where you say “Now, suppose that our object_width (measured in pixels) is computed be 150 pixels wide (based on its associated bounding box) ”
Why 150 Pixels? 😀
We need to know (1) the size of the reference object in pixels and (2) the size of the reference object in actual, measurable dimensions. Once we have both these values we can compute the triangle similarity and thereby compute the size of other objects in our image.
OK thanks for answering, but what happens if the object is a square oh rectangle would be lxl and bxh to know the area in pixels?
and sorry but I do not understand why you got 150Pixels the size of the object of the coin?
: D
150px was an example. It was used to demonstrate how the triangle similarity equation can be used for basic calibration.
Hi Adrian,
Is it possible to get this output like dimension of objects which we measured into csv files from disk.
Thanks!
A CSV file is just a comma separated list of strings. Open a file pointer and write the coordinates obtained via Lines 68-75 to disk.
hi Adrian, I have the same thing as pawan mentioned. The measuring only worked on the first object on the left, and not measuring any other object in the pic.
My guess here is that the other objects in the image were not properly detected. Please take a look at the
edged
image to ensure the contours of the objects are properly revealed. You might need to update the parameters to the Canny edge detector and erode/dilation operations.I fixed it, it’s just the structure of the code is not right.
if we make a picture over the background, you need help with this issue
what can i do if i have to measure more complex shapes and then make the CAD model of that shape ?
Hello Adrian,
Thank you for the nice explanation, but I have a problem. I still can’t figure out how the “contourArea” function works, because when I use it, some bigger areas are not detected (but they should be). And when I remove the checking area, the bigger area that was not shown before shows up, including those small noisy areas.
I tried to print the contourArea and I saw that in many cases, area that looks cleary large in the image has a very small contourArea value, where on the other hand small areas or noisy areas have got bigger contourArea values, this is the thing that is causing problem. Do you think the contourArea function has any fault at measuring the contour areas?
Hi Ahmed — that is indeed some very strange behavior. To be totally honest I’m not exactly sure what the issue would be. I would have to see the contours that were being correctly marked and then incorrectly marked first.
Hey Adrian,
Thank you for this code, but when I compile, it only show the coin at the right corner. I tried the 3 images but still the same. How can I let it show the sizes of the all of the objects?
That is certainly odd. Try investigating the edge map via
cv2.imshow
. If there are discontinuities along the outline thencv2.findContours
will not be able to extract the coin.Hi Adrian, I also tried the same on my Windows Laptop but it is still the same, the boundary with the dimensions only shows on the left corner coin & It is stuck there, not moving forward as you shown in the output image. Please help!
Click the window by OpenCV and press any key on your keyboard to advance execution of the script.
Hi Adrian,
First of all congratulations for your posts they are quite helpful.
Regarding “the pixel per metric” ratio, assuming that the camera distance is the same, is it applying to the whole image? I mean the objects close to the edges on the camera frame will have the same pixel ratio than the ones are in the middle?
Thanks.
Correct, and that is a limitation of this method. We assume a “straight on” view of the object. If the viewing angle changes the distance will change and this method cannot account for that.
Hi Adrian,
Thanks for the reply, in order to clarify, would it work fine (the object measurement) if for example in the FIgure 3 we move some of the tablets closer to the frame edges?
Technically yes, but the size measurement would start to get more distorted. This is a simple method for object size measurement. For a more accurate method we would need to calibrate our camera and account for “barrel distortion” caused by the camera lens. The Embedded Vision Alliance has a nice writeup on this.
Thanks Adrian for the answer,
I’ve got one more question,
If we change the camera-objects distance obviously we have to re-calibrate to get the new pixel/mm ratio but, would that ratio be lineal if we change the camera distance? or should we calibrate the ratio for different distances?
Correct, the relationship would be linear. You can move either the object or the camera but not both. If you move both you would need to recalibrate.
Hello Adrian
Thank you very much for the post.
I am trying to measure defect sizes of a component from an image taken. I know that the width of the component in mm is the width of the whole image. So will the pixelPermetric will work in the same way as having a reference object?
Thank you in advance
Yes, provided you know the exact width you can still use the triangle similarity method covered in thsi post.
Hi Adrian,
As a requirement for a project, I need to find the height(pixel value) of a human object (head to feet). For this I want to find and mark top of the head and bottom of the feet. Then the distance between two points in pixels. Up to now I have done following steps (pre-processing).
Load the image (human body with T-pose)
Converted into gray-scale and blur
Performed edge detection
Performed dilation+erosion
Next what should I do for the next step??
I would recommend using a “human detector” of some sort instead. Try using this detector from OpenCV or this deep learning-based one.
Is there a way to do this in java?
Yes, but you would need to port the code to Java + OpenCV.
error: (-215) scn == 3 || scn == 4 in function cvtColor
This is the error I’ve got !
Double-check the file paths to your input images. The “cv2.imread” function is likely returning “None” implying that the input image could not be found.
maybe you forget putting / infront of home
like home/pi/… should be /home/pi/…
Hey Adrian,
Many thanks for you effort and time building this wonderful website and projects. These samples helped me very much finishing very big part of my project.
May I ask you about contours and minAreaRect , do they produce perfect rectangle with perfectly equal sides or it’s not a perfect rectangle ? .
Also if so, what if I need to measure the dimensions of all sides of rectangle to compare the dimension of each side to each other using tr, tl, br, bl points. How can I define these points and then use the dist.euclidean function after ? or there is a better way to do it ?
sorry I am not professional in coding !
Many thanks in advance!
It’s not a perfect square. It’s the minimum enclosing bounding box which could be rectangle with non-equal sides.
Thanks Adrian Very much ,, then can you please tell me how to measure the length of each side of the bounding box?
Compute the Euclidean distance between each vertex of the rotated rectangle. Apply triangle similarity to obtain the final dimensions.
args = vars(ap.parse_args())
Hi adrian
while executing the above line it is not executing and giving error” args is not defined” and we have sucessfully completed the above lines and giving width of image as 0.955 and imported the image sucessfully
Did you download the source code to this post using the “Downloads” section? Or copy and paste? Make sure you download the code to ensure you didn’t accidentally introduce errors during the copy and paste.
hi adrian
we have successfully downloaded the source code and imported the modules and only that single line is not executing that is
args = vars(ap.parse_args())
and the next lines are not executing due this error so please help us in solving this particular problem
You should read up on command line arguments before continuing — that post will resolve your issue. I hope that helps.
Hi Adrian,
Is there any way to calculate the area of United States Quarter
The area of a circle is A = pi * r^2. The radius would be half of the width (or height) provided you are measuring a circle.
Hello,
I have read with interest your blog post regarding “Measuring size of objects in an image”. I am in the initial phases of determining the feasibility of evaluating metrics of an object in a photo. In the perfect world, I want to be able to take 1 or more pictures with a standard phone-camera, upload those photos to a central processing or cloud based server, and then evaluate dimensions, colors, etc. I have some background in aerial imagery, fiducial marks, ground based control, etc. However, doing something on the scale of an object approximately the size of a letter-size sheet of paper is more difficult. The objects i have in mind, I believe it would be feasible to overlay a “calibration card” into the photo. The calibration card could help give real dimension and color to the photo for scale and color rectification? I am looking to bounce some ideas of off an expert in this photogrammetry field if you would be so kind to entertain my thoughts. I understand camera lenses, etc present issues as well.
thank you!
If you have a calibration card of some sort that would be ideal. I would also suggest computing the intrinsic/extrinsic parameters of the camera to provide more accurate measurements.
Hi Adrian,
Is there any way to calculate the area of these objects?
If you know the width and height you can compute the area of the bounding box region.
Great work Adrian. is there a way of calculating the weight of an object in a picture. If yes plz how can I get it done.
thank u.
This tutorial demonstrates how to compute the width and height so I’m not sure what you are asking.
Hi,
The article is very interesting and useful one. I run the code in PyCharm IDE and following error was occurred.
usage: object_size.py [-h] -i IMAGE -w WIDTH
object_size.py: error: the following arguments are required: -i/–image, -w/–width
Can you please tell me how to solve this?
Please see this post on command line arguments.
i am suffering from same problem.. command line arg.. plz help me to sort out..
Read the post linked to above, Mili. It will sort you out and help you understand commend line arguments 🙂
thank you adrian.. 🙂
need to save this data, height and width to excel file. please help me.
PyImageSearch mainly discusses computer vision and deep learning. Writing simple text data to disk is a basic file I/O operation. I would highly suggest you learn the fundamentals of programming before continuing as computer vision is significantly more advanced. Take the time to invest in yourself now and you’ll be able to build wonderful applications in the future 🙂
Hi Adrian,
I tried to install the imutils after typing:
soruce ~/.profile
workon cv
pip install imutils
…..but was intsalled in /usr/local/lib/pyhton3.4/dist-packages
I expected to be installed in python2.7 in order to work with this version.
Any suggestion ?
Can you share your full terminal commands + output in a GitHub Gist? I’m not sure why it would be installing to the system Python if you are inside the Python virtual environment. Guess is that either the “source” or “workon” command failed.
Can you list out all the applications of the project in real life.
Use your imagination, give it some thought, and do a bit of research. I am confident you can create your list 🙂
sir , I also have the same doubt, what are the various application of this project
it would be use in Site construction acceptance.it can reduce large cost
Hi Adrian… great tutorial, really informative and helpful… one typo which you might want to correct: in the “pixels per metric” ratio section I think this sentence
“Thus implying there are approximately 157 pixels per every 0.955 inches in our image…”
was meant to be
“Thus…157 pixels per inch in our image”..if there are 150px in 0.955inch, then there are 157px in 1 inch…it is not a big deal though 🙂
Hi Adrian, it is a really a great tutorial. I am doing hand measurement for my project. I want to measure every single fingers’ measurement, palm breadth and palm length(from the middle bottom of index finger to the end of the palm) based on image. But, I don’t know how to locate the exact points, for example, on top of the every fingers and their bottom point at the middle of the line of the intersection between palm and fingers. Can you give me some guidelines and reference how to locate the points?
You’ll want to take a look at contour properties, including convexity defects and the convex hull. I have a lesson inside the PyImageSearch Gurus course that demonstrates how to locate each of these regions along the hand. I hope that helps point you in the right direction or at the very least gives you additional terms to Google and research.
Hi, Adrian, thank you for sharing more and more of such a useful ideas!
After handling with an implementation of your model, but in real time, I have been thinking about making it more robustness as an object detector.
Some ideas popped out, I’m sharing with you and asking for your opinion, thank you in advance for your time!
1. As you said a reference object has to be ‘easy-to-see’, what do you think about implementing ArUco Markers as so, maybe in this case we could get rid of the ‘top-left order’ function?
2. While moving objects, numbers (obviously) get changed. Can we someways keep track of it? Extended Kalman filtering? Tracking function?
3. While working with real-time recognition, boundingRect() causes flickering, is there any way to control it, please, any tips?
Thanks Artemii, I’m glad you enjoyed the tutorial. And congrats on porting it to a real-time implementation. To address your questions:
1. Yes, you could use ArUco markers here. You could also train your own custom object detector if you wished. As long as you know the measurements of those markers beforehand.
2. Take a look at correlation filters. They are very useful for tracking.
3. I don’t think the bounding rectangle function itself is causing the flickering, it’s more likely that your method used to detect the marker is not detecting the marker in certain frames. You may want to double-check that function.
Hello Adrian, your tutorials is really great, thank you for sharing.
I have a question, i’m brazilian, and there is almost no references about opencv.
I have some knowledge in english but i’m not fluent, so it’s little hard.
I’m doing my final paper, and i want to do, with raspberry pi3 and picamera, monitor the growth of a plant in size, so,
I’m thinking of taking a picture every day of the plant and analyzing its size and making a graph that represents its growth.
Could you direct me to something that would help me? I’m a beginner in python and raspberry.
Thank you, and sorry for bad english.
There are a few ways to approach this but the two key components are:
1. Create a script/cronjob that snaps a photo every N hours (or days)
2. Create a script that can analyze the size of the plant
Since your camera will be fixed and non-moving ideally some basic background subtraction between the subsequent frames will give the differences between the two plants. From there you could measure it. If you’re new to Python and OpenCV I would recommend reading through my introductory book, Practical Python and OpenCV. This book will help teach you the fundamentals of OpenCV and enable you to better approach this project. From there you can apply the background subtraction technique from this blog post.
do you have a tutorial to analyze the size of the plant or any object in image?
This blog post discusses how to measure the size of an object in an image. If you want to measure the size of a plant you’ll want to determine how you are going to detect it, either via:
1. Basic image processing operations
2. Machine learning
3. Segmentation
4. Object detection
Hi Adrian, thanks for great tutorial. Is there some changes needed to get accurate result for images taken from 180 degree.
Do you have an example image of what you are working with?
Hello Adrian
I am new in this computer vision (and Programming in general!). I came from Agricultural Engineering, and the only experience I have in programming is Visual Basic that I studied as part of the curriculum for mere three months.
I came here to finish my undergraduate thesis regarding measuring weight of cattle using smartphone camera (by analyzing their chest size, thus I need to know how to measure the dimension).
Before I can get into that project, my teacher decided to challenge me by telling me to create a program to determine an object’s area that captured using camera. He told me that I can use any kind of programming language. Currently, it’s just a simple box, which mean it’s just length x width. He told me “it should be simple, if you can’t do it then you can’t proceed to your thesis”. The challenge here is he want me to get the area regardless of camera distance to object. So, if I capture the image from 1 meter or 3 meter, the result will always the same.
Okay enough with my background. I google on how to do it, and I found this tutorial. Thank God!
But now I am stuck looking at this page for hours, without knowing what exactly I need to do. As others might say, I do not know what I do not know.
Will you help me by answering some of these questions ?
1. What should I do first? I know I should study hard, but starting from?
For your info, I have Windows 10. I already install Python and Sublime Text 3. Should I do all of these Python programming in Linux instead? Assume I am a complete newbie in programming, all that I have is ability to learn, capability to understand English, computer, 24H internet, my brain and my willpower.
2. Is there any additional references for me to study computer vision, python, etc?
3. OOT, The end goal of my undergraduate thesis is to create an Android app that is capable to measure weight of cattle using camera. FYI, I have not learn Java and Android Studio. In your honest opinion, by implementing technique here plus studying Android and its stuffs, do you think an average guy can finish it in 4 months? I am highly motivated enough to do impossible stuff, but I want rationale opinion. None of my friends are expert in this matter.
Right now I feel completely lost, but I must do this (you may wonder why agriculture degree decided to do programming? It is common nowadays that some of students here decided to learn programming, whether for fun, business, or academic purpose ; regardless of their department)
I am sorry to write this wall of text. One thing for sure, I am 100% ready to learn, I just need guidance on what should I do first, especially with tons of materials and knowledge available all over the internet. No matter how difficult it is, I will do it.
Thank you and sorry for my bad english
P.S : I already subscribe to your email course
Congrats on starting your project. But if you are new to programming your first step would be to learn how to program. I would recommend learning how to write code in Python as you’ll be using Python quite a bit with computer vision. The RealPython course would be a good one for you to get up to speed.
Secondly, you’ll want to work through my book, Practical Python and OpenCV. This book explains, line by line, what each line of code and what each function are doing. It’s by far the fastest way to get up to speed with the OpenCV library and learn the fundamentals of computer vision and image processing. In fact, many readers have used the book to learn both Python and OpenCV at the same time!
Take your time learning Python and OpenCV. It won’t be easy if you are new to writing code but if you practice each day I’m confident you can do it.
Hello Adrian,
This is a very useful tutorial for me as I am working on a course project that involves identifying objects (coins) and I am doing so using size. I have seen the same issue that measurements of the same coin type are not equal.
First-off I need to get a stable hands-off setup with a tripod that looks at the center of my flat object surface at 90 deg. After that I am considering using a script for camera calibration. I have a question on this however, even if the calibration is perfect won’t a coin at the image center measure differently from a coin at the edge of the field-of-view just due to the perspective?
The size difference between a dime and a penny are not that great 17.91 mm versus 19.05 mm diameter so the accuracy of measurement needs to be within +/-0.57 mm. Currently my camera is about 15 inches above the surface and the field-of-view is about 45 deg so center to image edge is about 6 in in my case.
Thank you for all your great blogs,
Brian
There are a few ways to approach this problem, but yes, a full blown intrinsic/extrinsic camera calibration will give you the best measurement in accuracy here. That said, you’ll also want to make sure you can segment the coins from the background. If you cannot segment the coins you will not be able to perform the measurement.
I see 2 error as below:
1. pixels_per_metric = 150px / 0.955in = 157px
Here the unit of the result is px/inch, not just px.
2. Thus implying there are approximately 157 pixels per every 0.955 inches in our image. Using this ratio, we can compute the size of objects in an image.
Here it is 157 pixels per every 1 inch not 0.955 inches.
is this tutorial works in matlab?
The code for this tutorial is written in Python. You would need to translate it to MATLAB.
hi, can you help me i have filtering image from front-end to measure the human body can use this way to finish this measurement.
There are a few ways to approach this, but if you want a super accurate method, you might want to consider a segmentation network, like UNet or Mask R-CNN to first extract a person, and ideally with a calibrated camera. From there you could make your measurements.
hello sir, can u help me.?
how many distance, image to camera in your sample.?
thanks
I did not measure the distance from my camera to the objects. Perhaps you are are referring to this tutorial?
hello sir. thanks for the reply. my friend, ahsan. he want ask the distance between object n camera. is that any certain distance?
As I mentioned in my first reply, I do not know the distance between the object and the camera for this blog post.
Hi Adrian
I have python 2.7.13. And when i run object_size.py and distance_between.py , the program just stops after bounding box for the quarter. I never see the output for other objects. Can you suggest what I might be doing wrong.
You need to click the window opened by OpenCV then press any key on your keyboard to advance the execution of the script.
Hi Adrian thanks again for the nice tutorial, but I have a question:
I want to do the same thing in a car detection, where I want to find the length of car or object from a real time cam, there I have no reference object, do you know how do handle it?
I would appreciate your job and thank in advance.
You will need a reference object in some capacity, whether that’s using the method here or computing the intrinsic/extrinsic parameters of the camera, likely during a “checkerboard calibration”.
Hello Adrian, thanks for the great tutorial. I would like to know your opinion about solving the object size prediction problem using deep learning, I am not able to find any research papers or projects solving a similar problem using DL.
Just because you can solve a problem using DL doesn’t mean you have to, on in this case, should. The most accurate measurements are going to come from calibrated cameras and multi-view geometry.
Great tutorial and precise work.
Have you thought about a version for mobiles? iOS especially?
Kind regards.
Thanks, I’m glad you enjoyed the tutorial! I don’t have any plans to create a mobile version of this guide but provided you understand the function calls in this post you can translate the code to OpenCV on whatever mobile platform you are using.
Thanks Adrian for the great Tutorial,
this code is helping me a lot. I am new to opencv and python in general.
Is there a way to have this code run through numerous pictures at once rather than do each picture individually?
Kind regards
I’m not sure what you mean by “run through numerous pictures at once”. Could you clarify?
Additionally, if you are new to OpenCV and Python I would recommending working through my introductory book, Practical Python and OpenCV. This book will teach you the fundamentals of OpenCV and better prepare you for the more advanced tutorials here on PyImageSearch. Be sure to take a look!
in your example_01, you have the code run through only the image ‘example_01.png’.
I have a folder which has 93 images in it.
Is there a way to get the code running all of them at once?
For further info:
I have changed the code slightly, so that it gives me the measured size in a text document. So it would be handy if I could have all images run through the code at once rather than do them one by one. This way I could have the text document have all the text data I need and I can then see in which picture there could be a measurement error or mishap
Yes, you can use the “list_images” function in the imutils library to supply your directory of 93 images and loop over them.
I was wondering if instead of your example:
python object_size.py –image images/example_01.png –width 0.955
where you only go check the one image ‘example_01.png’, if you could for example check many pictures from a folder all at once.
python object_size.py –image images/examplefolder/*.png –width 0.955
I would suggest modifying the code to either:
1. Accept wildcards
2. Or simply use the
list_images
function in the imutils library. An example of which can be found here.Can we detect object length/width by placing object on a graph paper?I am trying to calculate leaf length and width in an image.Suggest some image processing techniques.Plz
Yes you can, but you would need to know:
1. The size (in terms of inches or millimeters) of each box in the graph paper or the size of the graph paper itself
2. Be able to detect each of the cells on the graph paper
From there you can compute the ratio of the number of cells on the paper to the number of cells the object takes up.
Hello Adrian.
Thank you for this guide, it is very helpful. I am taking my first steps with openCV and this example of measuring items in a picture is actually what I need…
Is there a similar example in Java for such a use of openCV ?
I could not find anything similar to what you have published with Java, must examples I could find for openCV are written with Python.
Thank you,
Angel
Hey Angel — OpenCV bindings do exist for the Java programming language, but you would need to port the code from Python to Java.
If I have a image of a web page taken from a 5mp phone camera, how do I get the coordinates, color, width, height and any other attributes of an HTML object in that image.
I’m curious why you would be using a phone camera? Why not just load the webpage and then inspect the computed element attributes using the HTML and CSS?
Can we achieve the same with OpenCV only.I am working on android.
Yes. You will need to:
1. Implement my “imutils” function in Java + OpenCV
2. Implement the distance function in Java which is also easy
Hello ! Thank you very much for this !
I have a question, please, how I can see all rectangles and sizes in one time without press ‘Enter’ for each object ?
And so, save the global resulting image ?
Thx 🙂
Move these lines to the bottom of the Python script:
Additionally, you can use the
cv2.imwrite
function to write images to disk.If you’re new to working with OpenCV I would recommend you read through Practical Python and OpenCV so you can learn the basics first.
Thanks for your wonderful article Adrian. The explanation is so clean and well explained.
Thank you Niranjan, I really appreciate your kind words 🙂
Hello
Thanks for this great article it really helped me out.
How can I crop each object so it has its own image? What I mean is I want every single object that is detected cropped so nothing else is visible. What code should I write?
Thank you very much
Do you want to crop out each object and then save the object to disk? Or are you trying to have a single image with only the objects themselves visible?
Hi Adrian
I want to measure the millimetre radius of the object in real time, but I don’t know where to start. I ran your sample project, but I couldn’t calculate it as milimetric. And also how do I run the webcam on Windows? Thanks in advance
Hi,
Thanks for your script.
I run the script and once object is detected.
How display the size of all objects?
Thanks.
Click on the window opened by OpenCV and then press any key on your keyboard to advance the execution of the script.
Hi Adrian, I have posted a question on stackoverflow: https://stackoverflow.com/q/52360556/7322816
I was wondering if you can take a look at let me know if you have any ideas?
Thanks
Hi…..soo i actually wanted to determine the actual size of the object from an image…using this :-
object size in image = Object size * focal length / object distance from camera
can we find out the real size of objects using this equation given that i know the object distance from the camera and focal length….
can we get the object size in image in any units of length instead of pixels ?? if so…how can we do that ??
Hi Adrian, I see that you extracted the contour information on line 35, then sort it on line 39 to go left to right direction. The cv2.findContours also outputs the hierarchy information (if using cv2.RETR_TREE). If I would like to sort the contour information like you did on line 39 together with the hierarchy information, how do I do that?
Can I contribute to the above problem statement ?
I’m not sure what you mean, Sayantika. Could you clarify?
hi Andrian,
great work. .
Is there any way to identify the distance of camera from the image taken? is there any way to identify the focal length from the image only?
You mean something like this post?
Hello Adrian
Amazing walk though and description of the script – especially helpfull since im fairly new with python programming at this “level”.
Atm. im working on a project that takes base in the operations preformed in this tutorial – however i got a question regarding to the bounding box that are used to find the bounds of the contours to get the lengths of the objects.
For example if im interested in finding the “precise” area of the object on the image and the square is a 15×15 but somewhere along the object there are a “bump”, an indentation on the object or the lines on the object was not in a perfect 90 degree angle leading to some small variances in width from top left corner to bottom left corner.
Is there anyway the box operation could be made to take more “points” into consideration when making the measurement or any other solution/function that would be better suited.
I hope that you understand my question and thanks in advance.
-Simon
It sounds like you may be interested in a far more accurate measurement than what this code will give you. I would suggest looking into more advanced forms of camera calibration, including computing the intrinsic and extrinsic parameters of the camera.
I will look into the camera parameters. However i tried the code from the example here and i got more then decent results ( around 1 cm off the real size, sometimes even smaller) leading me to the though that it if i could take multiple midpoints and sum over the object instead that it would provide me with a better result. My hope is to estimate the size within 1mm of error. and so far i have gotten it down to 4mm with this code and smaller corrections and modifications in camera position etc.
If it makes it easier – im more to happy to take by email ?
– Simon
Hi Andrian,
Thanks for this lucid and nice tutorial.
Could you suggest a way to measure the height of a human from monocular images using a reference object such as a credit card, whose size is known? . I assume a similar approach used in this tutorial could be used for that purpose. No?
It is a very similar approach to this tutorial. You would want to apply an object detector to detect the bounding box of the person first, then, once you have the bounding box, you can use your reference object to compute the height. This tutorial will help you get started on the person detection component.
Dear Adrian,
Sincere apologies for mis-spelling your name.
I have tried following this post several times to get particle sizing on an image for my company. The sample that I am taking an image of has small particles (millimeter sizing) What would you recommend to get this accurately grab individual beads instead of hundreds at a time? I can email pictures of the output if that would help clarify what is going one. Thanks.
Hey Colton, without seeing example images of what you’re working with it’s hard to provide an exact suggestion, but my guess is that you’ll need a more accurate camera calibration for this. Feel free to email in the image though and I’ll try to take a look.
Hi Adrian! I have the same problem. The code has been working great with a sample that I came up with that had a much bigger object size. I need to analyze images that have circular shapes with diameters in the range of 50/40 microns. It seems like the script only recognizes width to the certain extent. Were you and Colton able to figure anything out regarding smaller sized objects? Thanks in advance!
How are you computing object width in pixels directly? Please reply asap .TY
Hey Saad — this blog post actually discusses how I’m converting pixels to actual measurable units. Is there a particular aspect of the post that is confusing you?
Hi,tank you Adrian
I have a very big size object (Area rug) in camera and can not scroll window. how can scroll or zoom ?
OpenCV’s GUI functionality is very basic and meant only for debugging. You cannot zoom or scroll using OpenCV’s GUI functions.
Hi, Adrian. Thank you for writing this great article!
I have question, how to measure width and length of nonsymmetric object (e.g. corn kernel)? Thanks.
That’s a much more challenging problem. I would start by asking how exactly do people measure the dimensions of a kernel of corn? What is the “standard”? Once you know the answer to that question, then you can start considering how to create a computer vision application to perform the measurement.
Hi Adrian,
I’m looking to do something similar with a bit more precision in order to measure the length and diameter of screws. How would you approach this problem?
Thanks
I would suggest looking into the intrinsic and extrinsic camera parameters which will allow you to obtain a much more accurate calibration.
Dear Adrian,
I am working on a project in which we need to input this height and width into another system which is already have been developed. How can i save this data I.e. height and width both into a file. Like text file or excel. How could I perform it? Plz let know..
Thanks in advance.
I would suggest looking into a CSV file which could naturally be read by Excel.
Hi Adrian,
Thank you for sharing this awesome tutorial.
But I was wondering how to deal when the objects are placed closely and sometimes overlayed to one another.
Any input on that?
Look forward to hearing!
That is significantly more challenging. If the objects partially overlap you’ll want to look into instance segmentation algorithms which will help you estimate the center of the object.
Hi Adrian,
I have problem in which I have to measure the size of eye-pupil. Using haar cascade I was able to get the box co-ordinate of eye with which I found the centre position of eye, but how to exactly find the size of pupil? Could you help me out?
You should use facial landmarks rather than Haar cascades to localize the actual eye regions. From there you can localize the pupils.
Hi adrain,
Thanks a lot for the suggestion, I tried using facial landmarks approach and was able to localise the iris region. If I want to go further towards pupil region what can I do, could you help me with some suggestions?
I personally haven’t tried this tutorial but I know other PyImageSearch readers have had good luck with it. That would be my primary suggestion.
Superb Tutorial Adrian. Thanks very much. I continue to learn. It is almost becoming an Art.
In addition, the comments and questions teach me a lot more. God bless y’all.
Thank you Suresh! I’m so happy you are developing your computer vision skills. Keep it up!
Hello! Very nice job!
I suppose it does not work for perspective 3D (find dimensions of a box, for example). Am I right? If yes, could you mentiony alternative for that?
Thank you!
Correct, this method will not work for 3D and finding the dimensions of a box. I don’t have any tutorials for that specific use case but I will consider it for the future.
Hi, is this to possible to find out the dimension of tyre from a vehicle’s image using this script ? ie. i doesn’t want to find the entire object’s size but some part of object .
Thank you,
Yes, you could use this method but you would want to train an actual tire detector first. You won’t be able to use simple image processing to reliably find a tire in an image.
Thank you Adrian.
You are welcome, Bashi!
Hi Adrian. I take pictures of one person and put a reference object around it. But it does not calculate correctly. what’s the reason?
Can you be a bit more specific regarding “but it does not calculate properly”? What is incorrect regarding the calculation?
excuse me,
I want to get human height and width from image. There is no reference object in the original image. Can I manually put a reference object in the image? While doing this, but do not calculate the height and width of the person properly.
thanks a lot
You will need to perform some sort of calibration, whether be a reference object or explicitly computing the intrinsic and extrinsic parameters of the camera. Some form of calibration is required.
Great stuff!
Reading carefully I might have found a typo.
“The pixels_per_metric is therefore:
pixels_per_metric = 150px / 0.955in = 157px
Thus implying there are approximately 157 pixels per every 0.955 inches in our image. ”
should be “there are approximately 157 pixels per every inch” 🙂
Hi Adrian thank you for this course
I have this problem if I run “object_size.py,Line 7, in from scipy.spatial import distance as dist
importError: No module named scipy.spatial”
But I install scipy.
Please help me
Are you using Python virtual environments? If so, make sure you install SciPy into your virtualenv:
Hi! could you teach me how to do this size measurement in real-time implementation 🙂
Thanks in advance your help is much appreciated!
You can combine the code from this post with my tutorial on the VideoStream class to achieve your goal.
I tried combining the codes then Undervoltage and Over temperature warnings started to pop up. Any advice?
Sorry, without knowing what specifically the warnings are I cannot provide any suggestions. If you can provide them I can try to help.
For running this code ,open cv and python these two software is required whether numpy is required .
OpenCV returns images as NumPy arrays, so yes, NumPy is required.
Hi Adrian, really good article, thanks!
I’m currently working in an application where I have to measure objects displacement within a 2d plane. I’m thinking to workout the pixel metric ratio using a known distance reference points in that plane, but the camera is pointing in angle of 30°
Will it give me accurate results with the camera in that angle? Or would the camera need to be at 90°?
Thanks
The camera would need to be 90 degrees. For your application you will need a more advanced camera calibration. Look into computing the intrinsic and extrinsic camera parameters.
Hi Adrian,
Thanks for the reply,
I’m familiar with the calibration process (extrinsic and intrinsic and image to world transformations) but I’m trying to find a workaround to this as I think is a bit tedious…
As only I’m interested in a 2d plane measurements, would it work if I do a perspective transformation of the image to place the reading plane perpendicular to the camera FOV (90 degrees)?
(I’ve seen that you’ve got a few posts explaining how to do the perspective transformation)
thanks.
A perspective transform could work as long as you maintain the aspect ratios of the objects. That said, you really need to perform an intrinsic/extrinsic calibration for the most accurate measurements.
Thanks for the tutorial, is it possible to get exact dimensions (area occupation in image or percentage)?
Yes, very easily. Since you know the width and height of the image/frame along with the width and height of the detected object you can simply compute the ratio between the two which will give you area of occupation.
Yeah, but, I’m mostly working with irregular shapes, that includes many different corners and having hard time to get the perfect result from the image, for example, a car, or a truck on an aerial imager for tracking. I want to extract the information of, how much space car allocates in the image and want to combine that information with variable zoom to keep the shape percentage stable by varying the zoom between 1x to 50x using GPIO function on the raspberry pi with motorized zoom lens etc. (I want it to work like automated – scripted dolly zoom to be clear, if the occupation increases zoom out, if it decreases zoom in)
Thank you so much for this great tutorial. I’d like to use an object as a scale in this exercise but I want to look for a specific color and then measure that object and use its pre determined dimensions as a scale to find another objects dimensions. Example: I have a box id like to find the dimensions of one face, I place a round blue sticker n its face and take a picture, then use the blue sticker as the scale.Is this possible?
As long as you know the size of the blue sticker, yes. You detect the blue sticker you should use color thresholding. See this tutorial for an example of color thresholding.
Thanks Adrian for the detail explanation of the script.
please I have a question, I want to build an app that tell the actual size of the different human body using their picture.
1) If I carry out image segmentation and apply this tutorial to it, will it give me the accurate measurement of each part?
2) different people use different types of camera that may affect the size of the Image. please do you have any suggestion on how to go about this, that know matter the camera type when once you insert your image it will still give the accurate measurement.
3) also dose large pixel size equal to large image size?
thanks in advance.
If you want to use this method to calculate the size of a person you will need to ensure that the end user’s camera is calibrated first, there is no other way around that.
Thanks Adrian, But is there any other method aside from this one?
Yes, you’ll want to explore computing the intrinsic and extrinsic camera parameters for a more accurate camera calibration.
Hi Adrian,
I wish to calculate the length of a free swimming tuna at surface in a video image I took using 4K video shot by a drone camera. The image was taken by the camera pointing vertically downwards but the tuna is near the edge of the image. I accurately know the drone elevation above the water surface thanks to a micro-radar altimeter attached to the drone. I also have accurate data for the camera sensor height and width, the camera focal length, and the Ultra HD video image resolution (4096 x 2160). I can easily calculate the Ground Sample Distance (GSD) but how do I make distortion corrections for the tuna being near the edge of the frame ?
Have you performed a camera calibration via the intrinsic/extrinsic camera parameters to remove circular lens distortion? That would be the next step. Once you’ve performed that correction you’ll be able to accurately measure the tuna size.
Thanks Adrian. I’ll do that.
Hi Adrian
I am currently working on an thesis project which i have to make a wound measurement application that will give the length , width and the depth. for the depth am going to use stereo vision depth using two cameras and what i would like to know if i added the pixel per metric method i can get the length and the width and near should i be to the wound. thanks you
Take a look at computing the intrinsic and extrinsic parameters of your camera. That will lead to a more accurate depth, width, and length measurement.
Hi Adrian, truly nice tutorial, many thanks ! I am working on a project to measure complex/curved shapes (for instance some shapes will look like an “S”. Your method works somehow as it have the rectangle around the “S” shape, and i can deduct a lenght and a width.
However i wonder if you know a method in opencv or in another framework to measure the length of the “S” shape. Say you take this “S” shape and stretch it up to the point where you get a straight line, i am looking for an method to measure the length of this resulting line. Any idea or hints ? Thanks a lot
If you were to “stretch” the “S” until it was a straight line that would just be the process of:
1. Skeletonization
2. Using
cv2.countNonZeros
to count the total number of foreground pixelsWould that work for your problem?
thanks for the guidance Adrian, I’ll give it a try and let you know
Hello Adrian, not sure why but the program is showing me just the measure of the coin nothing else? any hints please, i followed all tutorials and i cannot see any errors?
Thanks
Sof
Click on the window opened by OpenCV then press any key on your keyboard to advance execution of the script.
Thanks Adrian, working now,
Fantastic, glad to hear it 🙂
I want to measure the inner and outer diameter of a ring help me to do this now i only measure the outer diameter.
Are you following any of my tutorials? What tutorial did you use as a starting point? Secondly, keep in mind that this method will return only external contours. If one ring is embedded in another the embedded ring will not be found. You’ll want to update the
cv2.RETR_EXTERNAL
to becv2.RETR_TREE
.Hello!
I tried the above program for satellite images to find homes in a neighbourhood, but couldn’t get that. Any advice as to how I can do that?
How can i measure the size of an object without keeping the reference object in every image , i can give the pixels taken by an object of known dimension taken from the camera at a reference position to start with
You don’t need the reference object in every image. Once you’ve detected the reference image and computed the focal length you can store those variables and them remove the object.
The pixels_per_metric is therefore:
pixels_per_metric = 150px / 0.955in = 157px
Thus implying there are approximately 157 pixels per every 0.955 inches in our image. Using this ratio, we can compute the size of objects in an image.
this lines, i thinks it should be 157 pixels per everey 1 inch, isn’t it?
The program is throwing error everytime when i run it.could u please help me out.
Thanks in advance.
Traceback (most recent call last):
AttributeError: module ‘imutils’ has no attribute ‘grab_contours’
I have already upgrated the package imutils.
It sounds like you have not actually upgraded the “imutils” library. Double and triple-check that you have upgraded successfully. If you are using virtual environments make sure you are accessing the virtual environment before upgrading.
Hi Adrian!
The program is taking input via the command line, how is it possible to take input through a gui?
Yes, but you would need to choose a GUI framework to work with. PyImageSearch is a computer vision so I only cover computer vision and deep learning here. You can add any GUI methodologies you want but you would need to implement such functionality yourself.
Hi Adrian, Thanks for your great tutorial,
I have two questions.
1. is it always mandatory the reference object to be at the left corner?
2. is it possible to use two reference objects while taking images?
I have implemented your idea but got the measurement of only one object. In your code, the object width is automatically calculated and assigned to dB variable. I did the same, I also have the dimensions of the reference object. but don’t know why it is only measuring one object. Maybe is because my object is not in the left corner.
would love your suggestions and help.
1. The reference object can be anywhere you want in the image (provided you can detect it).
2. Yes, absolutely.
Hi Adrian
My goal is to measure only the height of an object in the same way.
I am using IP Camera to collect the images.
However, this object will disappear from the image at a certain time and then appear in the image.
I put your example inside a while and it works fine. But when the object disappears from the image I get the following error:
cv2.imshow(“Camera de Medicao”, orig)
NameError: name ‘orig’ is not defined
At a certain time I will have no outline in the image. This error is caused for this reason, I would like to know how to correct this validation. For when the algorithm does not encode contour it continues.
Thanks!
There is a logic error in your code. Somewhere you are defining a variable named “orig” but once an object has disappeared that variable has not been assigned. You’ll need to debug your code.
If I wanna to make a UI for this project with Visual Studio or maybe PyQT. How could I do it?
I would start by referring to this tutorial on OpenCV + TKinter.
Hello Adrian!
Your blog is very helpful and the way you explained this is awesome. But, I’m having a problem. When I run the downloaded source code, Stable image just appear with the size dimensions of reference object (extreme left object in the image) only.
Can you help me out ?
Thanks
Click on the window opened by OpenCV and press a key on your keyboard to advance execution of the script.
Problem resolved.
Thanks
Hi Adrian,
Thanks for this wonderful blog!
I am trying to apply your code to my image which is a image of fish put on a scale.
I need to measure it’s length.
For my use case can you please suggest me with what changes in your code I can achieve this?
I have sent you a sample image in your mail also.
Please suggest.
You would first need to detect the fish itself. Have you tried using object detection for that task?
Hello, I was wondering where/how/what I should change to make the reference image a black square and then the shape that I need to measure blue. I know how to mask the colors of the image but I do not quite understand where I should put everything in the code or what variable I should change to make it so that the reference image is NOT the leftmost item.
Hi, is there any programming language source code that is available? and can I integrate this to my application? let’s say I am using an IDE – React Native.
As far as I understand, OpenCV should be able to integrate with React Native but I’ve never done it before. If you look for OpenCV and React Native tutorials you should likely find some.
Hi
This is very useful. Can this technique be used to obtain particle size distribution in a SEM image. Please explain further. Thank you.
Which camera used in this project it means camera detail ?
I used my iPhone camera to capture these example images.
Many minute details on the object are getting captured , so can i replace “for c in cnts” somehow so that , only once the box is drawn around the object and no inner boxes
i have modified the reference image with a custom pixelpermatrix ratio and i am not using a reference image , if there are 3 squares on the image i want only one to get recognized and i want the program to stop there for example the leftmost object as we are sorting contours , i dont want the next objects to get detected when i press the keyboard
Hi, this has been very helpful for me and i have a doubt. Is there a formal documentation on this method?
What do you mean by “formal documentation”? The tutorial itself serves as documentation.
Hello Adrian
I am really enjoying the tutorial. I actually have a production use for measuring objects in a photograph. My first problem was not enough of a contrast when using grey scale to get the outlines using edged = cv2.Canny(gray, 50, 100). So I found another tutorial you had using the HSV color and inRange to create a mask then use Canny function. That works great. However when use cv2.findContours I am getting back 2 contours for each object in the masked image. Not real sure where to go from here?
Hey Bob — what flags are you passing into the “cv2.findContours” function?
Hey Adrian I figured it out I think. I was not blurring the image. So I think I was getting a contour from just inside the edge and a contour from just outside the edge. So I added using the GassuanBlur function and I am getting back one contour now. The flags I was using are cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE.
Congrats on resolving the issue, Bob! Nice job.
It stuck on coin .it give the dimension of the coin and remain on it nothing change and cmd also stuck just cursor blink .so i press key enter but nothing work and the same issue with me in distance measurement tutorial of you ..kindly help me
Click on the window opened by OpenCV and press any key on your keyboard to advance execution.
Hi Adrian,
I am working on a project similar to this but when I execute the above code on cv I get a error mentioning no module named “cv2” and no module named “scipy” I followed your instruction on this site: https://www.pyimagesearch.com/2018/09/26/install-opencv-4-on-your-raspberry-pi/
I did everything as you mentioned on site above mentioned. Pls can help me out from here.
1. Make sure you are in your Python virtual environment before accessing the code (assuming you have OpenCV installed properly).
2. Install SciPy on your RPi:
$ pip install scipy --no-cache-dir
Hey Adrian !
What is the optimum resolution for this script ?
thanks .
The optimum resolution really depends on:
1. How large the objects you want to detect and measure are.
2. How far away from the objects your camera are.
For small objects that are farther away from the camera you would need higher resolution, for example.
Hi Adrian,
1. How do I change the unit from inch to centimeter?
2. How do I write the measurements to a file?
Best,
Saswat
1. 1in = 2.54cm. I trust that you can perform the conversion now, give it a shot!
2. You need basics Python file I/O. If you’ve never performed file I/O before make sure you learn the basics of Python first.
Hi Adrian,
I want to send the measurement to ubidots and to my own website that I am about create, Can help me a bit I really don’t what to do? It’s okay to skip ubidots for me but my main task is to send the measurement to my website. I am going to create the website with Microsoft Visual Studio.
Sorry, I don’t have any experience with Udibots. How to you interact with it? Via an API of some sort?
Yes using ubidots Api, then how about creating my own website and put data over there may I know how to store measurement in the pi and send it over to website.
I’m not sure how the Udibots API works but I assume it’s a REST interface. You could use a package like Python’s “requests” and then send it to the API service.
Hi, Adrian
Is it possible to fix the distance between the pi camera and the objects that I am going to measure so that the size of objects is fixed no matter how the camera is moved? If I can standardize the distance then no need reference object right? Because my project requires to measure the size of objects without the reference object. Hope you can help me. Thank you.
You’ll need the reference object at least once even if the camera distance is fixed (you still need to compute the “pixels per metric” ratio). Just serialize the values to disk and then in subsequent runs load them and use them (no need to perform additional calibrations if you’re using the same camera AND that camera does not move).
How and where to serialize the values to disk?
Please take the time to look into basic file I/O with Python. Make sure you understand how to read and write data from disk. Once you understand that, come back and write your calibration to disk and then load it from your Python script.
Hi Adrian,
How and where to serialize the values to disk like what you just said?
How to measure the exact object in the image that I wanted to measure precisely. I took a picture using the Pi camera, but the output does not show the correct measurement of the object. I was wondering why I need –width 0.955 to measure the size of the object and can I measure without the width thing?
hi so i have tried your code but the width of the object but the measuring size of the objects only stayed on one of the object and is not moving around as shown above.
Click on the window opened by OpenCV and press a key on your keyboard to advance execution of the script.
is it possible to implement this code into yolov3 object detection ??
Yes, start by using this tutorial on YOLO.
Hi Adrian,
1st thanks for the post its really helped me a lot to understand with object size detection,
however i am working in a small project recently and i find your post it almost full fill my purpose, but if i use any photo with different angel like 3D type ot doesn`t go well, coz BoxPoint draw box out of my object. coz that object contain height,width and depth. so i want to draw those boxpoint following my contours then i want to measure the size of contours is it possible or do you have any other idea or have you done anything like that, if you then would you give me some reference of suggestion ? it will be so much helpful for me i am stuck with that problem right now.
Hi Adrian,
I am using this code to measure grains but it is unable to make separate contours for touching grains. Can you guide me in this regard?
You should use the watershed algorithm.
I think you make small mistake
You say:
Thus implying there are approximately 157 pixels per every 0.955 inches in our image. Using this ratio, we can compute the size of objects in an image.
But correct 157 equal 1 inch
great article 🙂
Adrian, can you guide how we can implement human face dimension measurement.
You mean measure the width and height of a face in an image?
Hi which is a best camera for computer vision for real time calibration ?
Very Thanks for your code.
Can I measure object size on flow system such as conveyor using only a usb camera ?
Yes, provided that:
1. You can detect the object on the conveyor
2. And you have calibrated your camera
Hi I like to know is it possible to identify human chest part from a given image, same like this I like to find the distance between left chest to right chest, is it possible?
Again, Thank you for this comprehensive tutorial and others in your Free 17-day crash course.
I have applied the code to different images and I am able to get pretty accurate measurements in most cases.
Two questions:
1) In many cases, I am able to get contours and measurements of only a few of the objects in
the image… How can I solve this issue and results for all the objects?
2) If I want to selectively choose the objects I am interested to measure and receive only the measurements of their external size, versus receiving measurements of every contour detected on them.
For example, a regular door with a carved design inside will give the contours of the external and the internal lines, even though we use cv2.RETR_EXTERNAL.
Any guidance you can provide would be great.
Thank you!
Thanks Tedi, I’m glad you enjoyed the course. As for your questions:
Are they your own custom objects? If so, adjust the detection procedure, including pre-processing steps. You may need to train your own custom object detector as well. Secondly, it would help seeing your example images. Perhaps email me?
Yes, I will send them.
hello Adrian Rosebrock
I’m doing a project on artichokes to find the directions and determining the size of multiple artichokes in an image. Will this code is useful to check the direction and size of it.
In case, if not useful can you help me with some other tips.
I’m not sure what you mean by the “direction” of an artichoke?
Direction from Stem to the Tip of an Artichoke.
Can you please guide me how to find the measurement of detected objects? I am a student and doing my project based on it.
The tutorial you’re commenting on shows you how to measure the sizes of objects. Make sure you give it a read.
Hi Adrian nice article.
Object measurement size shows as based on image pixels. if i suppose to change image width or image quality , measurement size will be changed. how do i find exact size of the object?
Thanks in advance.
If you change the image quality or sensor you’ll need to recalibrate before you can measure object sizes.
When I run it with a quarter and a credit card, it only gives me the size of the quarter, not the card.
Any idea why?
Click on the window opened by OpenCV and press a key on your keyboard to advance execution of the script.
hi,could you provide paper about the project?
You can just reference this blog post. There is no paper for it.
Hi Adrian,
your all posts are awesome!
I’m working on a image processing project,where I’m looking for the spatial position of the object in the frame.
kindly help
Hie, how do i detect one object first in an image before measuring it?
I’m a beginner in computer vision and machine learning . I’m trying to build a model for easy checkout in departmental stores. Where I’m asked to identify the product based on it’s size.
My questions are as follows :
1. will this model (shown in blog) be sufficient ? will it be necessary to change the reference object depending on what objects we are going to measure ?
OR
2. should i have to use any reconstruction techniques to measure the size of the object ?( they didn’t mention anything about number of cameras to be used.)
OR
3. Can we use MASK R-CNN to measure the size of the object ?
(Can we make use of the labeled pixels to measure the dimensions of the object? as it creates a mask using all the pixels belonging to the object ? )
1. You only need your reference object once (when the script starts up) in order to perform the calibration.
2. Why do you need reconstruction?
3. Mask R-CNN would give you a pixel-wise mask for the object which you could then use to compute the object dimensions.
Can you have any video describe how to download and setup openCV on MacOS . I tried to setup but I am can’t.
I need to use OpenCV to measure object dimensions related to known object size.
You can follow my OpenCV install guides to install OpenCV on your macOS system.
hello adrian,
firstly, thanks a lot for making premium content freely available.
i am trying to get human body measurements from a picture where input will be the height of
the person, i have done pixel wise mask for individual parts of the body using mask rcnn but
problem here is , how to find out the measurements of irregular / polygonal shape like human
arm and legs etc.. how to get the measurements precisely
please help me out !
Take a look at methods such as OpenPose and instance segmentation algorithms, which combined together, will generate a pixel wise mask that you can use to (1) segment the person from the image and (2) then localize specific structures of the body.
Could you please show how to find concavity of letter in a word image?
Refer to OpenCV’s documentation on contours. You can compute the “convexness” of contour using OpenCV’s contour functions.
Hey Adrian, loved the tutorial!
I am working on a project and a part of it involves getting the measurements of the object in 3D.
So the main objective is to look at the object (currently focusing on cubes/cuboids) and calculate the volume.
How could I use the information you have provided to further get the 3rd dimension as well? I am using a Stereo vision camera so I have the depth information
Any help will be appreciated. Thank You!
I don’t have any tutorials on 3D measurement. I may cover it in the future, thanks for the suggestion!
Dear Adrian,
Thanks for your blogs.
I tested your blog ( Measure object size ) using my images. I found that all small parts of images is detect and I need only the bigger object not all details.I used my I phone to take photos.
I need only to get dimension of the hole object not the small parts of the objects.
Please help me to solve this problem.
Best Regards,
Assem
Hi Adrian
Really enjoying Practical Python and OpenCV as well as the blog.
I’ve been wondering about the GaussianBlur arguments, it seems to me that the optimal blurring kernel size is dependent on the size of the image.
Have you found a good rule of thumb for optimizing these? Maybe width // 100? Or is it preferable to just resize all images to the same size before blurring?
Thanks!
I’m so happy to hear you are enjoying Practical Python and OpenCV, Ford!
Yes, you are correct that the image size will have a dramatic impact on the final output blurred image. Typically you would eitehr:
1. Resize your images to a known, canonical size and then blur it.
2. Develop your script for images of a known dimension and then compute the ratio of the image size to the kernel size.
In practice #1 is more often used as its far more easier to implement.
Background color should be always Black? Does it work with other colors for background?
You need to be able to segment objects such that they are “white” on a “black” background. The actual background color of the original image does not matter provided you can segment the foreground from the background.
Our team is working on pdf and we need to detect table from pdf. we tried lots of but we cant do that still we are trying to work on pdf table can you please help me.
thank you 🙂
Nice tutorial, Adrian. Very thorough! I have one question though. Assuming I positioned the camera in a 90degree pole looking down on the objects. I have the reference object (penny) and a rectangular box ( 10cm x 20cm x 40cm, [length, width, height] ).
Will this code still get the correct measurement of the bounding box?
Hello,
this is what I am looking for. Is it possible to use it in blender to meansure texture images?
Sorry, I don’t have any experience with Blender.
Thank You for very useful article. i read “Find distance from camera to object/marker using Python and OpenCV” article and then i have one question. in article “Find distance from camera to object” which we get already depth value and then if i have to calculate scale of object in image by i know depth between camera to object. in this article not use depth in calculated so my question is if i would have use depth in calculate join this article. do you know how to use it?
I have some problem with camera calibration and undistorted image. I take some picture of chessboard after that I using algorithm (cv2.calibrateCamera) but the results ( intrinsic parameter) have high vary for each chessboard image .
I wondering which is more accuracy.
I also undistort the image but it is more distort than the initial image
Can you help me solve this problem?
I don’t have any tutorials on using the “cv2.calibrateCamera” function yet but I will try to cover it soon for you!