QR code detection and distance estiamtion

 avatar
unknown
python
2 years ago
4.5 kB
7
Indexable
import cv2 as cv
import numpy as np
import math
import pyzbar.pyzbar as pyzbar
import betterLook

# Variable
camID = 1  # camera ID, or pass string as filename. to the camID

# Real world measured Distance and width of QR code
KNOWN_DISTANCE = 30.1  # inches
KNOWN_WIDTH = 5.0  # inches

# define the fonts
fonts = cv.FONT_HERSHEY_COMPLEX
Pos = (50, 50)
# colors (BGR)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
MAGENTA = (255, 0, 255)
GREEN = (0, 255, 0)
CYAN = (255, 255, 0)
GOLD = (0, 255, 215)
YELLOW = (0, 255, 255)
ORANGE = (0, 165, 230)

# functions

# finding Distance between two points


def eucaldainDistance(x, y, x1, y1):

    eucaldainDist = math.sqrt((x1 - x) ** 2 + (y1 - y) ** 2)

    return eucaldainDist


# focal length finder function


def focalLengthFinder(knowDistance, knownWidth, widthInImage):
    """This function calculates the focal length. which is used to find the distance between  object and camera
    :param1 knownDistance(int/float) : it is Distance form object to camera measured in real world.
    :param2 knownWidth(float): it is the real width of object, in real world
    :param3 widthInImage(float): the width of object in the image, it will be in pixels.
    return FocalLength(float):"""

    focalLength = (widthInImage * knowDistance) / knownWidth
    return focalLength


def distanceFinder(focalLength, knownWidth, widthInImage):
    """
    This function basically estimate the distance, it takes the three arguments: focallength, knownwidth, widthInImage
    :param1 focalLength: focal length found through another function .
    param2 knownWidth : it is the width of object in the real world.
    param3 width of object: the width of object in the image .
    :returns the distance:


    """
    distance = (knownWidth * focalLength) / widthInImage
    return distance


def DetectQRcode(image):
    codeWidth = 0
    x, y = 0, 0
    euclaDistance = 0
    global Pos
    # convert the color image to gray scale image
    Gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)

    # create QR code object
    objectQRcode = pyzbar.decode(Gray)
    for obDecoded in objectQRcode:

        points = obDecoded.polygon
        if len(points) > 4:
            hull = cv.convexHull(
                np.array([points for point in points], dtype=np.float32)
            )
            hull = list(map(tuple, np.squeeze(hull)))
        else:
            hull = points

        n = len(hull)
        # draw the lines on the QR code
        for j in range(0, n):
            # print(j, "      ", (j + 1) % n, "    ", n)

            cv.line(image, hull[j], hull[(j + 1) % n], ORANGE, 2)
        # finding width of QR code in the image
        x, x1 = hull[0][0], hull[1][0]
        y, y1 = hull[0][1], hull[1][1]

        Pos = hull[3]
        # using Eucaldain distance finder function to find the width
        euclaDistance = eucaldainDistance(x, y, x1, y1)

        # retruing the Eucaldain distance/ QR code width other words
        return euclaDistance


# video recording
# fourcc = cv.VideoWriter_fourcc(*'XVID')
# out = cv.VideoWriter("Demo.mp4", fourcc, 15.0, (640, 480))

# creating camera object
camera = cv.VideoCapture(camID)

refernceImage = cv.imread("referenceImage2.png")
# getting the width of QR code in the reference image
Rwidth = DetectQRcode(refernceImage)

# finding the focal length
focalLength = focalLengthFinder(KNOWN_DISTANCE, KNOWN_WIDTH, Rwidth)
print("Focal length:  ", focalLengthFinder)

counter = 0

while True:
    ret, frame = camera.read()

    # finding width of QR code width in the frame
    codeWidth = DetectQRcode(frame)
    # print(Value)
    # print(codeWidth)

    if codeWidth is not None:

        # print("not none")
        Distance = distanceFinder(focalLength, KNOWN_WIDTH, codeWidth)
        # cv.putText(frame, f"Distance: {Distance}", (50,50), fonts, 0.6, (GOLD), 2)

        betterLook.showText(
            frame,
            f"Distnace: {round(Distance,2)} Inches",
            Pos,
            GOLD,
            int(Distance * 4.5),
        )
    # out.write(frame)

    cv.imshow("frame", frame)
    key = cv.waitKey(1)
    if key == ord("s"):
        # saving frame
        counter += 1
        print("frame saved")
        cv.imwrite(f"frames/frame{counter}.png", frame)
    if key == ord("q"):
        break
camera.release()
cv.destroyAllWindows()
# out.release()
Editor is loading...