OpenCV2以测量图像中对象之间的距离

问题描述

所以我有一个程序可以测量图像中两个对象之间的距离。但是,程序会自动将最左边的对象作为“参考图像”。例如,我一直在努力将参考对象更改为中心的正方形。

我能成像的唯一方法是使用Python Pillow计算图像的中心坐标,然后使用它们创建一个“方形”参考对象。但是,我一直在努力做到这一点。我在下面包含了未更改的代码

任何帮助将不胜感激。

# USAGE
# python distance_between.py --image images/example_01.png --width 0.955
# python distance_between.py --image images/example_02.png --width 0.955
# python distance_between.py --image images/example_03.png --width 3.5
# python distance_between.py --image images/example_04.jpg --width 1.0

# 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,help="width of the left-most object in the image (in inches)")
args = vars(ap.parse_args())

# 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,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,then initialize the
# distance colors and reference object
(cnts,_) = contours.sort_contours(cnts)
colors = ((0,255),(240,159),(0,165,(255,255,0),255))
refObj = None

# 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
    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)

    # compute the center of the bounding Box
    cX = np.average(Box[:,0])
    cY = np.average(Box[:,1])

    # if this is the first contour we are examining (i.e.,# the left-most contour),we presume this is the
    # reference object
    if refObj is None:
        # unpack the ordered bounding Box,then compute the
        # midpoint between the top-left and top-right points,# followed by the midpoint between the top-right and
        # bottom-right
        (tl,tr,br,bl) = Box
        (tlblX,tlblY) = midpoint(tl,bl)
        (trbrX,trbrY) = midpoint(tr,br)

        # compute the Euclidean distance between the midpoints,# then construct the reference object
        D = dist.euclidean((tlblX,tlblY),(trbrX,trbrY))
        refObj = (Box,(cX,cY),D / args["width"])
        continue

    # draw the contours on the image
    orig = image.copy()
    cv2.drawContours(orig,[Box.astype("int")],-1,2)
    cv2.drawContours(orig,[refObj[0].astype("int")],2)

    # stack the reference coordinates and the object coordinates
    # to include the object center
    refCoords = np.vstack([refObj[0],refObj[1]])
    objCoords = np.vstack([Box,cY)])
       
    # loop over the original points
    for ((xA,yA),(xB,yB),color) in zip(refCoords,objCoords,colors):
        # draw circles corresponding to the current points and
        # connect them with a line
        cv2.circle(orig,(int(xA),int(yA)),5,color,-1)
        cv2.circle(orig,(int(xB),int(yB)),-1)
        cv2.line(orig,2)
        # compute the Euclidean distance between the coordinates,# and then convert the distance in pixels to distance in
        # units
        D = dist.euclidean((xA,yB)) / refObj[2]
        (mX,mY) = midpoint((xA,yB))
        cv2.putText(orig,"{:.1f}in".format(D),(int(mX),int(mY - 10)),cv2.FONT_HERShey_SIMPLEX,0.55,2)

        # show the output image
        cv2.imshow("Image",orig)
        cv2.waitKey(0)

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)