Find Distance Between Points in Opencv

Hi,

I have a code that allows me to open an image and click to add points on the picture and it shows me their coordinates as shown below:

demo

The coordinates are already being displayed.
First x-y coordinates: (131,133)
Second : (28,242)
Third: (99,328)
Fourth: (111,321)

I need to find the linear distance between 2 successive points. That is:

  1. Distance between Second and First coordinates,
  2. Distance between Third and Second coordinates,
  3. Distance between Fourth and Third coordinates,

Example: (131,133) & (28,242)

Distance using √[(x₂ - x₁)² + (y₂ - y₁)²].

Can someone help, please?
Thanks!

My code:

import cv2
[print(i) for i in dir(cv2) if 'EVENT' in i]

# importing the module
import cv2


# function to display the coordinates of
# of the points clicked on the image
def click_event(event, x, y, flags, params):
    # checking for left mouse clicks
    if event == cv2.EVENT_LBUTTONDOWN:
        # displaying the coordinates
        # on the Shell
        print(x, ' ', y)

        # displaying the coordinates
        # on the image window
        font = cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText(img, str(x) + ',' +
                    str(y), (x, y), font,
                    1, (255, 0, 0), 2)
        cv2.imshow('image', img)

    # checking for right mouse clicks
    if event == cv2.EVENT_RBUTTONDOWN:
        # displaying the coordinates
        # on the Shell
        print(x, ' ', y)

        # displaying the coordinates
        # on the image window
        font = cv2.FONT_HERSHEY_SIMPLEX
        b = img[y, x, 0]
        g = img[y, x, 1]
        r = img[y, x, 2]
        cv2.putText(img, str(b) + ',' +
                    str(g) + ',' + str(r),
                    (x, y), font, 1,
                    (255, 255, 0), 2)
        cv2.imshow('image', img)


# driver function
if __name__ == "__main__":
    # reading the image
    img = cv2.imread('shirt.jpg', 1)
    img = cv2.resize(img, (0, 0), None, 0.2, 0.2)

    # displaying the image
    cv2.imshow('image', img)

    # setting mouse hadler for the image
    # and calling the click_event() function
    cv2.setMouseCallback('image', click_event)

    # wait for a key to be pressed to exit
    cv2.waitKey(0)

    # close the window
    cv2.destroyAllWindows()

sorry dear, we can try to help you with opencv related problems,
but we cannot mend your lack of general coding skills ;(

It is not about mending. Please read the question again.

yes it is. you already know the formula for the distance, yet your code contains not even an attempt to use it.

first step: in the click event handler, store those points. don’t just draw on the picture.

It seems you want to calculate distance between last point and previous point - so you have to keep previous point in external/global variable (at start you should set i.e. None) and when you click then you should check if you have previous point and calculate distance between new point and previous point. And later you should keep current point as previous point.

previous_point = None  # default value at start

def click_event(event, x, y, flags, params):
    global previous_point   # to assing new value to external variable

    font = cv2.FONT_HERSHEY_SIMPLEX

    if event == cv2.EVENT_LBUTTONDOWN:
        text = f"{x}, {y}"

        print(text)
        cv2.putText(img, text, (x, y), font, 1, (255, 0, 0), 2)

        cv2.imshow('image', img)

        if previous_point:  # check if there is previous point (not `None`)
            x2, y2 = previous_point
            dist = ((x-x2)**2 + (y-y2)**2 )**0.5
            print('distance:', dist)
                  
        previous_point = (x, y)  # keep it for next calculation

It will display distance after every new point like

131, 133
28, 242
distance: 149.96666296213968
99, 328
distance: 111.5212984142491
...

If you want to display first all points and later all distances then you would have to keep all points on (global) list and calculate distances after cv2.waitKey(0)


Full working code with other changes:

import cv2
import sys

previous_point = None  # default value at start

def click_event(event, x, y, flags, params):
    """Display the coordinates of the points clicked on the image"""
    
    global previous_point
    
    font = cv2.FONT_HERSHEY_SIMPLEX
    
    # left mouse
    if event == cv2.EVENT_LBUTTONDOWN:
        text = f"{x}, {y}"

        print(text)

        if previous_point:  # check if there is previous point
            x2, y2 = previous_point
            dist = ((x-x2)**2 + (y-y2)**2 )**0.5
            #print('distance:', dist)
            print(f'distance from {x2}, {y2} to {x}, {y}:', dist)
            
            cv2.line(img, (x, y), (x2, y2), (0, 0, 0), 2)
            
            # redraw previous point to hide beginning of line 
            cv2.circle(img, (x2, y2), 3, (0, 0, 255), -1) 
    
        cv2.circle(img, (x, y), 3, (0, 0, 255), -1)
        cv2.putText(img, text, (x, y), font, 1, (255, 0, 0), 2)
        
        cv2.imshow('image', img)

        previous_point = (x, y)

    # right mouse
    elif event == cv2.EVENT_RBUTTONDOWN:
        b,g,r = img[y, x, :]

        text = f"{b},{g},{r}"
        
        print(text)
        cv2.putText(img, text, (x, y), font, 1, (255, 255, 0), 2)

        cv2.imshow('image', img)


# driver function

if __name__ == "__main__":

    if len(sys.argv) > 1:
        filename = sys.argv[1]
    else:
        filename = 'test/lenna.png'
        #filename = 'short.jpg'
        
    img = cv2.imread(filename, 1)
    #img = cv2.resize(img, (0, 0), None, 0.2, 0.2)

    cv2.imshow('image', img)

    # setting mouse hadler for the image
    # and calling the click_event() function
    cv2.setMouseCallback('image', click_event)

    # wait for a key to be pressed to exit
    cv2.waitKey(0)

    # close the window
    cv2.destroyAllWindows()


Image Lenna from Wikipedia

2 Likes