I’m currently working on a project that requires detecting the orientation of a QR code. I’m using the qrcode library to detect the center of the QR code and then trying to orient it using a line. However, I’m facing issues due to lighting conditions affecting the detection for certain colors. The line is evident, but the parameters I’m using to detect the lines don’t seem to be effective.My objective is to detect the angle for the piece with the x axis.
I’ve tried various sources but still can’t reliably identify the line. I suspect the issue is that there are pixels in the image with the same intensity as the line.
I detected correctly the qrs and cropped the images. So, my problem is on the cropped image, because I need to detect this line, and usually it is doesnt work. Also if we can extract this orientation from the qr it could work, however, on the documentation of qreader I didnt find anything related. If someone knows a tool or way to resolve this, I would thank them.
from qreader import QReader
import numpy as np
from sklearn.linear_model import RANSACRegressor
qreader = QReader()
img = cv2.imread("frame_real.jpg")
QRs = qreader.detect_and_decode(image=img, return_detections=True)
plt.imshow(img)
# Filter QRs
availables_qrs = [(i,k) for i,k in enumerate(QRs[0]) if k is not None]
## Get QR most far
def compute_distance(x, y, image_center):
return np.sqrt((x-image_center[0])**2 + (y-image_center[1])**2)
detections_availables_qrs = [(i[1], QRs[1][i[0]]) for i in availables_qrs]
QR = min(detections_availables_qrs, key=lambda x: compute_distance(x[1]['cxcy'][0], x[1]['cxcy'][0], (img.shape[1]/2, img.shape[0]/2)))
print(f"cxcy: {QR[1]['cxcy']}")
print(f"{QR[0]}")
cx, cy = QR[1]["cxcy"]
cx = int(cx)
cy = int(cy)
radius = 110
bbox = QR[1]['bbox_xyxy']
img= cv2.rectangle(img, (int(bbox[0]), int(bbox[1])), (int(bbox[2]), int(bbox[3])), color=(0, 255, 0), thickness=1)
x_min, y_min, x_max, y_max = map(int, bbox)
cropped_img = img[cy-radius:cy+radius, cx-radius:cx+radius]
image = cropped_img.copy()
_, thresh_black = cv2.threshold(image, 100, 255, cv2.THRESH_BINARY)
_, thresh_white = cv2.threshold(image, 240, 255, cv2.THRESH_BINARY_INV)
result = cv2.bitwise_and(thresh_black, thresh_white)
hsv = cv2.cvtColor(result, cv2.COLOR_BGR2HSV)
lower_red_1 = np.array([0, 30,30])
upper_red_1 = np.array([10, 255, 255])
lower_red_2 = np.array([160, 30, 30])
upper_red_2 = np.array([179, 255, 255])
mask1 = cv2.inRange(hsv, lower_red_1, upper_red_1)
mask2 = cv2.inRange(hsv, lower_red_2, upper_red_2)
mask = cv2.bitwise_or(mask1, mask2)
coords = np.column_stack(np.where(mask > 0))
ransac = RANSACRegressor()
X = coords[:, 1].reshape(-1, 1)
y = coords[:, 0]
ransac.fit(X, y)
line_X = np.arange(X.min(), X.max())[:, np.newaxis]
line_y_ransac = ransac.predict(line_X)
inlier_mask = ransac.inlier_mask_
line_coords = coords[inlier_mask]
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title('Original')
plt.subplot(1, 2, 2)
plt.imshow(mask, cmap='gray')
plt.scatter(line_coords[:, 1], line_coords[:, 0], color='red', s=1)
plt.plot(line_X, line_y_ransac, color='blue', linewidth=2)
plt.title('Line')
print(np.degrees(np.arctan(-(line_y_ransac[-1]-line_y_ransac[0])/(line_X[-1]-line_X[0]))))
Image with the qr code
Image cropped 1
Image cropped 2
Image cropped 3
Has anyone encountered similar issues or can point me to documentation or methods to improve line detection under varying lighting conditions? Any help would be greatly appreciated!
Thank you!
Documentation or suggestions to adjust the parameters or ideas to resolve my problem would be helpful.
Michael Smith is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.