Acer1968

QR code orientation

May 25th, 2021 (edited)
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.29 KB | None | 0 0
  1. """
  2. DEMOUKÁZKA
  3. jak pomocí OpenCV přečíst hodnotu v QR kódu a zároveň vrátit orientaci QR kódu podle směrnice.
  4. Vypíše směrnici QR kódu jako úhel 0°- 360°
  5. Vypíše světovou stranu, na kterou je QR kód natočen
  6. """
  7. import cv2 as cv
  8. import numpy as np
  9. import math
  10.  
  11. # Nastavím si testovací obrázek:
  12. # qr000.png (neotočen, originál míří na SEVER)
  13. # qr015.png (lehce pootočen o 15° PO směru hodinových ručiček)
  14. # qr345.png (lehce pootočen o 15° PROTI směru hodinových ručiček)
  15. # qr045.png (pootočen o 45° PO směru hodinových ručiček, nedává správné výsledky, protože je to hraniční hodnota a záleží, kolik desetinek doprava či doleva spočítá OpenCV ty hraniční body a tím pádem směrnici)
  16. IMG_FILE = 'qr015.png'
  17. # Když chci podrobný tisk informací o QR kódu, které předá OpenCV, nastavím True
  18. PODROBNY_TISK = False
  19. # Když chci nakreslit obrysové čáry kolem QR kódu, nastavím True
  20. KRESLENI = True
  21. im = cv.imread(IMG_FILE)
  22. det = cv.QRCodeDetector()
  23. for i in range(4):
  24.     # postupně vyzkouším obrázek vždy pootočit o 90°, proto 4 cykly
  25.     print("Rozměry obrázku: ", im.shape)
  26.     retval, points, straight_qrcode = det.detectAndDecode(im)
  27.     if points is not None:
  28.         nrOfPoints = len(points[0])
  29.         x0 = int(points[0][3][0])
  30.         y0 = int(points[0][3][1])
  31.         if KRESLENI:
  32.             """
  33.            Zelené kolečko je výchozí bod směrnice. Ta vede z tohoto bodu směrem k levému hornímu rohu QR kódu a tím pádem určuje "světovou" stranu, kam je QR kód natočen.
  34.            Čáry jsou obrysy QR kódu. Prvním bodem vráceným z OpenCV je levý horní roh. Od něj začíná červená čára, která se mění v růžovou čím blíže jsou obvodové čáry k poslednímu bodu. Červená tedy ukazuje na první bod.
  35.            Pokud chci vykresli kolečko i obrys QR kódu, nastavím konstantu KRESLENI na True.
  36.            """
  37.             cv.circle(im, tuple((x0, y0)), 25, (0, 250, 30), 4)
  38.             for j in range(nrOfPoints):
  39.                 x1 = int(points[0][j][0])
  40.                 y1 = int(points[0][j][1])
  41.                 nextPointIndex = (j+1) % nrOfPoints
  42.                 x2 = int(points[0][nextPointIndex][0])
  43.                 y2 = int(points[0][nextPointIndex][1])
  44.                 cv.line(im, tuple((x1, y1)), tuple((x2, y2)), (75*j,75*j,255), 5)
  45.     if PODROBNY_TISK:
  46.         print("Obsah QR kódu: ", retval)
  47.         print("Surová data na souřadnicích QR kódu: ", straight_qrcode)
  48.         print("Typ matice se souřadnicemi: ", type(points))
  49.         print("Počet dimenzí matice: ", points.ndim)
  50.         print("Tvar matice: ", points.shape)
  51.         print("Velikost matice: ", points.size)
  52.         print("Typ hodnot uchovaný v matici: ", points. dtype)
  53.         # print("Transformovaná matice, čili x- a y-    souřadnice bodů: ", points.T)
  54.         print("Největší prvek: ", points.max())
  55.         print("Nejmenší prvek: ", points.min())
  56.         # print("Index maximálních hodnot souřadnic: ", np.argmax(points))
  57.         # print("Index minimálních hodnot souřadnic: ", np.argmin(points))
  58.     print("Souřadnice rohů QR kódu: ", points)
  59.     delta_x = points[0][0][0] - x0
  60.     delta_y = y0 - points[0][0][1]
  61.     print("Delta x: ", delta_x, " Delta y: ", delta_y)
  62.     # Když ani jedna směrnice není kolmicí na osový systém, tzn. má obecný směr
  63.     if bool(delta_x and delta_y):
  64.         theta = math.atan(delta_x / delta_y)
  65.         theta_deg = theta / math.pi * 180
  66.         if delta_y < 0:
  67.             theta_deg = 180 + theta_deg
  68.     # Když směrnice ukazuje kolmo nahoru (SEVER) nebo dolů (JIH), nastala by chyba, protože tangens není pro takové hodnoty úhlu definován
  69.     elif delta_x == 0:
  70.         if delta_y > 0:
  71.             theta = 0
  72.             theta_deg = float(0)
  73.         else:
  74.             theta = math.pi
  75.             theta_deg = float(180)
  76.     # Když směrnice ukazuje kolmo doprava (VÝCHOD) nebo doleva (ZÁPAD), nastala by chyba dělením nulou, tak to musím ošetřit
  77.     elif delta_y == 0:
  78.         if delta_x > 0:
  79.             theta = math.pi / 2
  80.             theta_deg = float(90)
  81.         else:
  82.             theta = math.pi / 2 * 3
  83.             theta_deg = float(270)
  84.     # Když se pohybuji v záporných hodnotách úhlu, chci ale vidět kladné číslo
  85.     if theta_deg < 0:
  86.         theta = theta + math.pi * 2
  87.         theta_deg = theta_deg + 360
  88.     window_name = "Smernice: " + str(round(theta_deg, 2))
  89.     if (theta_deg > 225.0) and (theta_deg <= 315.0):
  90.         direction = "ZAPAD"
  91.     elif (theta_deg > 45.0) and (theta_deg <= 135.0):
  92.         direction = "VYCHOD"
  93.     elif (theta_deg > 135.0) and (theta_deg <= 225.0):
  94.         direction = "JIH"
  95.     else:
  96.         direction = "SEVER"
  97.     window_name += " QR kod je orientovany na " + direction + ". Stiskni libovolnou klavesu pro otoceni QR kodu o 90°."
  98.     print("Text v QR kódu: ", retval, window_name, sep=" ")
  99.     cv.imshow(window_name, im)
  100.     # Stiskem klávesy budeme pokračovat
  101.     cv.waitKey(0)
  102.     cv.destroyAllWindows()
  103.     # Nechci znovu kreslit do už pokresleného obrázku, tak si znovu otevřu nepokreslený a otočím si ho tolikrát, kolik cyklů už proběhlo
  104.     im = cv.imread(IMG_FILE)
  105.     for k in range(i+1):
  106.         im = cv.rotate(im, cv.ROTATE_90_CLOCKWISE)
  107.  
Add Comment
Please, Sign In to add comment