One, project analysis
The idea of object size measurement is to find an object with a certain size as a reference and calculate the size of the unknown object based on the known ones.
As shown in the picture below, the size of the green board is 220*300 (unit: mm), and the length of the white paper is calculated through the program.
Mainly through image processing technology, the size measurement of objects in a picture is achieved. The specific requirements are as follows:
-
Read in a picture that contains the object that needs to be measured
-
Perform edge detection on the image to find all contours
-
Select the contour with the largest area among all contours, which is the object to be measured.
-
Perform a perspective transformation on the object to turn it into a rectangle
-
In a rectangle, determine the height and width of the object through the intersection points of the line segments.
-
Convert height and width to actual dimensions and label them on the image
-
Display the results on the screen.
Second, implementation process
- Import the necessary libraries: cv2 and numpy.
import cv2
import numpy as np
2. Define some parameters: scaling ratio, width and height of the output image.
scale=2
wP = 220 * scale
hP = 300 * scale
3. Define a function getContours
to obtain the contours in the image. This function first converts the image to grayscale, then performs Gaussian blur, then performs Canny edge detection, then performs dilation and erosion operations, and finally uses the findContours
function to find all outer contours. Perform contour filtering based on the conditions of area and number of inflection points, and return the filtered contour list.
def getContours(img, cThr=[100, 100], showCanny=False, minArea=1000, filter=0, draw=False): imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) imgBlur = cv2.GaussianBlur(imgGray, (5, 5), 1) imgCanny = cv2.Canny(imgBlur, cThr[0], cThr[1]) kernel = np.ones((5, 5)) imgDial = cv2.dilate(imgCanny, kernel, iterations=3) imgThre = cv2.erode(imgDial, kernel, iterations=2) if showCanny: cv2.imshow('Canny', imgThre) # Find all outer contours _, contours, _ = cv2.findContours(imgThre, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) finalCountours = [] # Traverse the found contours for i in contours: area = cv2.contourArea(i) # Area of the contour if area > minArea: # If it is greater than the set minimum outline value, go down peri = cv2.arcLength(i, True) # The length of the closed contour approx = cv2.approxPolyDP(i, 0.02 * peri, True) # The inflection point of the closed contour bbox = cv2.boundingRect(approx) # Find the bounding box if filter > 0: # Do you need to filter contours based on the number of inflection points? if len(approx) == filter: # Number of inflection points, area, inflection point position, bounding box, outline finalCountours.append([len(approx), area, approx, bbox, i]) else: finalCountours.append([len(approx), area, approx, bbox, i]) finalCountours = sorted(finalCountours, key=lambda x: x[1], reverse=True) # Sort from large to small according to the outline size if draw: # Whether to draw the outline for con in finalCountours: cv2.drawContours(img, con[4], -1, (0, 0, 255), 3) return img, finalCountours
4. A function reorder
is defined to reorder the order of four points. Sort according to the maximum and minimum values of the sum and difference of the four points, and return the reordered points.
def reorder(myPoints): myPointsNew = np.zeros_like(myPoints) myPoints = myPoints.reshape((4, 2)) add = myPoints.sum(1) myPointsNew[0] = myPoints[np.argmin(add)] myPointsNew[3] = myPoints[np.argmax(add)] diff = np.diff(myPoints, axis=1) myPointsNew[1] = myPoints[np.argmin(diff)] myPointsNew[2] = myPoints[np.argmax(diff)] return myPointsNew
5. Define a function warpImg
for perspective transformation of images. Based on the four input points and the width and height of the output image, use the getPerspectiveTransform
function to calculate the perspective transformation matrix, then use the warpPerspective
function to perform perspective transformation, and transform the transformed image Make a cut.
def warpImg(img, points, w, h, pad=20): # print(points) points = reorder(points) pts1 = np.float32(points) pts2 = np.float32([[0, 0], [w, 0], [0, h], [w, h]]) matrix = cv2.getPerspectiveTransform(pts1, pts2) imgWrap = cv2.warpPerspective(img, matrix, (w, h)) imgWrap = imgWrap[pad:imgWrap.shape[0] - pad, pad:imgWrap.shape[1] - pad] return imgWrap
6. Define a function findDis
for calculating the distance between two points.
def findDis(pts1, pts2): return ((pts2[0] - pts1[0]) ** 2 + (pts2[1] - pts1[1]) ** 2) ** 0.5
7. Read the input image and scale it to the specified size.
path = 'E:\All_in\opencv\chicun.png' img = cv2.imread(path) img = cv2.resize(img, (0, 0), None, 0.18, 0.18)
8. Use the getContours
function to obtain the contours in the image, set the minimum contour area to 8000, the number of inflection points to 4, and return the filtered contour list.
img, conts = getContours(img, minArea=8000, filter=4)
9. Determine whether there is a contour. If it exists, find the inflection point position of the largest contour, use the warpImg
function to perform perspective transformation on the image, and return the transformed image.
if len(conts) != 0: biggest = conts[0][2] #The inflection point position of the largest contour # print(biggest) imgWrap = warpImg(img, biggest, wP, hP)
10. Use the getContours
function again to obtain the contours of the transformed image, set the minimum contour area to 2000, the number of inflection points to 4, and return the filtered contour list.
imgContours2, conts2 = getContours(imgWrap, minArea=2000, filter=4, cThr=[50, 50])
11. Traverse the filtered contour list, draw polygons and arrows for each contour, calculate the length in both directions, and then mark the length information on the image.
if len(conts) != 0: for obj in conts2: cv2.polylines(imgContours2, [obj[2]], True, (0, 255, 0), 2) nPoints = reorder(obj[2]) nW = round((findDis(nPoints[0][0] // scale, nPoints[1][0] // scale) / 10), 1) nH = round((findDis(nPoints[0][0] // scale, nPoints[2][0] // scale) / 10), 1) #Create arrow cv2.arrowedLine(imgContours2, (nPoints[0][0][0], nPoints[0][0][1]), (nPoints[1][0][0], nPoints[1][0][ 1]), (255, 0, 255), 3, 8, 0, 0.05) cv2.arrowedLine(imgContours2, (nPoints[0][0][0], nPoints[0][0][1]), (nPoints[2][0][0], nPoints[2][0][ 1]), (255, 0, 255), 3, 8, 0, 0.05) x, y, w, h = obj[3] cv2.putText(imgContours2, '{}cm'.format(nW), (x + 30, y - 10), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (255, 0, 255), 2) cv2.putText(imgContours2, '{}cm'.format(nH), (x - 70, y + h // 2), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (255, 0, 255), 2)
12. Display the result image and the original image, and wait for any key to be pressed to close the window.
? cv2.imshow('background', imgContours2) cv2.imshow('Original', img) cv2.waitKey(0) ?
Three, result display
Four, application prospects
-
Industrial measurement: In the industrial field, Opencv dimensional measurement can be used to detect whether the size of parts meets the specifications. For example, on the production line, you can take pictures of parts and use Opencv to measure the length, width, diameter and other parameters of the parts to ensure product quality.
-
Medical imaging: Opencv size measurement can be used in the field of medical imaging, such as measuring tumor size, blood vessel diameter, etc. in medical imaging such as CT and MRI. This is very important for doctors to help them make accurate diagnoses and treatment plans.
-
Building measurement: In the fields of construction and real estate, Opencv dimensioning can be used to measure the size of buildings, room areas, etc. By taking photos of buildings and using Opencv for measurements, architects, designers and real estate developers can help with planning and design.
-
Vehicle measurement: Opencv dimension measurement can be used in the transportation field, such as measuring the length, width, height, etc. of vehicles. This is very important for road design, bridge design, parking lot planning, etc.
-
Education and training: Opencv dimension measurement can be used in the field of education and training, such as measuring the size and weight of objects in physical experiments. By using Opencv for measurement, students can help students understand and master physical concepts more intuitively.
The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. OpenCV skill tree Home page Overview 23530 people are learning the system