QR ์ฝ๋ ์ธ์
OpenCV์ pyzbar ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ QR ์ฝ๋๋ฅผ ์ธ์ํ๋ ๋จ๊ณ์ ์ ๊ทผ๋ฒ์ ๋ค๋ฃน๋๋ค.
ํ๊ฒฝ ์ค์
ํ์ ์ํํธ์จ์ด ์ค์น
Visual Studio 2022 C Redistributable (64-bit) ์ค์น๊ฐ ํ์ํฉ๋๋ค. pyzbar ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ C ๋ฐํ์์ ์์กดํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
ํ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
pip install opencv-python
pip install pyzbar
pip install matplotlib
๊ธฐ๋ณธ ์ด๋ฏธ์ง ๋ก๋ฉ ๋ฐ ํ์
๊ธฐ๋ณธ ์ด๋ฏธ์ง ์ฝ๊ธฐ
์ฒซ ๋ฒ์งธ ๋จ๊ณ๋ก QR ์ฝ๋๊ฐ ํฌํจ๋ ์ด๋ฏธ์ง๋ฅผ ๋ก๋ฉํ๊ณ ํ๋ฉด์ ํ์ํฉ๋๋ค.
import cv2
import matplotlib.pyplot as plt
import pyzbar.pyzbar as pyzbar
# ์ด๋ฏธ์ง ๋ก๋ฉ
img = cv2.imread('../img/frame.png')
# matplotlib์ผ๋ก ์ด๋ฏธ์ง ํ์
plt.imshow(img)
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()
์ฃผ์ ํฌ์ธํธ:
-
cv2.imread()๋ก ์ด๋ฏธ์ง๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋ฉ -
plt.imshow()๋ก ์ด๋ฏธ์ง๋ฅผ ํ๋ฉด์ ํ์ -
์ด๋ฏธ์ง ํ์ผ ๊ฒฝ๋ก๊ฐ ์ ํํ์ง ํ์ธ ํ์
QR ์ฝ๋ ๋์ฝ๋ฉ
๊ทธ๋ ์ด์ค์ผ์ผ ๋ณํ ๋ฐ ๋์ฝ๋ฉ
QR ์ฝ๋ ์ธ์์ ์ํด ์ด๋ฏธ์ง๋ฅผ ๊ทธ๋ ์ด์ค์ผ์ผ๋ก ๋ณํํ๊ณ pyzbar๋ก ๋์ฝ๋ฉํฉ๋๋ค.
import pyzbar.pyzbar as pyzbar
# ์ด๋ฏธ์ง ๋ก๋ฉ
img = cv2.imread('../img/frame.png')
# ๊ทธ๋ ์ด์ค์ผ์ผ ๋ณํ (QR ์ฝ๋ ์ธ์์ ์ํด ํ์)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# ๊ทธ๋ ์ด์ค์ผ์ผ ์ด๋ฏธ์ง ํ์
plt.imshow(gray, cmap='gray')
plt.show()
# QR ์ฝ๋ ๋์ฝ๋ฉ
decoded = pyzbar.decode(gray)
print(decoded)
cv2.waitKey(0)
cv2.destroyAllWindows()
ํต์ฌ ๊ฐ๋ :
-
cv2.cvtColor()๋ก ์ปฌ๋ฌ ๊ณต๊ฐ ๋ณํ -
pyzbar.decode()๊ฐ QR ์ฝ๋ ์ ๋ณด๋ฅผ ์ถ์ถ -
๋์ฝ๋ฉ ๊ฒฐ๊ณผ๋ ๋ฆฌ์คํธ ํํ๋ก ๋ฐํ
QR ์ฝ๋ ์์ญ ์๊ฐํ
๊ฒฝ๊ณ ์ฌ๊ฐํ ๊ทธ๋ฆฌ๊ธฐ
์ธ์๋ QR ์ฝ๋ ์ฃผ๋ณ์ ์ฌ๊ฐํ์ ๊ทธ๋ ค์ ์์น๋ฅผ ์๊ฐ์ ์ผ๋ก ํ์ํฉ๋๋ค.
# ๋์ฝ๋ฉ๋ QR ์ฝ๋ ์ ๋ณด ์ฒ๋ฆฌ
for d in decoded:
# QR ์ฝ๋ ๋ฐ์ดํฐ ์ถ๋ ฅ
print(d.data.decode('utf-8'))
print(d.type)
# QR ์ฝ๋ ์ฃผ๋ณ์ ์ด๋ก์ ์ฌ๊ฐํ ๊ทธ๋ฆฌ๊ธฐ
cv2.rectangle(img,
(d.rect[0], d.rect[1]),
(d.rect[0] + d.rect[2], d.rect[1] + d.rect[3]),
(0, 255, 0), 20)
plt.imshow(img)
plt.show()
๋งค๊ฐ๋ณ์ ์ค๋ช :
-
d.rect: QR ์ฝ๋์ ์์น ์ ๋ณด (x, y, width, height) -
(0, 255, 0): BGR ์์ (์ด๋ก์) -
20: ์ ์ ๋๊ป
ํ ์คํธ ์ ๋ณด ์ถ๊ฐ
QR ์ฝ๋ ์์ ๋์ฝ๋ฉ๋ ํ ์คํธ ์ ๋ณด๋ฅผ ํ์ํฉ๋๋ค.
# QR ์ฝ๋ ์์ ํ
์คํธ ์ถ๊ฐ
text = d.data.decode('utf-8') # ๋์ฝ๋ฉ๋ ํ
์คํธ
cv2.putText(img, text,
(d.rect[0], d.rect[1] - 50),
cv2.FONT_HERSHEY_SIMPLEX,
3, (0, 255, 0), 2, cv2.LINE_AA)
๋งค๊ฐ๋ณ์ ์์ธ:
-
text: ํ์ํ ํ ์คํธ -
(d.rect[0], d.rect[1] - 50): ํ ์คํธ ์์น (QR ์ฝ๋ ์์ชฝ) -
cv2.FONT_HERSHEY_SIMPLEX: ํฐํธ ํ์ -
3: ํฐํธ ํฌ๊ธฐ -
2: ํ ์คํธ ๋๊ป -
cv2.LINE_AA: ์ํฐ์จ๋ฆฌ์ด์ฑ
์ค์๊ฐ ์น์บ QR ์ฝ๋ ์ธ์
์์ ํ ์น์บ QR ์ฝ๋ ์ค์บ๋
์น์บ ์ ์ฌ์ฉํ์ฌ ์ค์๊ฐ์ผ๋ก QR ์ฝ๋๋ฅผ ์ธ์ํ๊ณ ํ์ํ๋ ์์ ํ ํ๋ก๊ทธ๋จ์ ๋๋ค.
import pyzbar.pyzbar as pyzbar
import cv2
# ์น์บ ์ด๊ธฐํ (๊ธฐ๋ณธ ์นด๋ฉ๋ผ ์ฌ์ฉ)
cap = cv2.VideoCapture(0)
# ์ด๋ฏธ์ง ์ ์ฅ์ ์ํ ์นด์ดํฐ
i = 0
while(cap.isOpened()):
# ํ๋ ์ ์ฝ๊ธฐ
ret, img = cap.read()
if not ret:
continue
# ๊ทธ๋ ์ด์ค์ผ์ผ ๋ณํ
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# QR ์ฝ๋ ๋์ฝ๋ฉ
decoded = pyzbar.decode(gray)
# ์ธ์๋ QR ์ฝ๋ ์ฒ๋ฆฌ
for d in decoded:
x, y, w, h = d.rect
# QR ์ฝ๋ ๋ฐ์ดํฐ ์ถ์ถ
barcode_data = d.data.decode("utf-8")
barcode_type = d.type
# ๋นจ๊ฐ์ ์ฌ๊ฐํ์ผ๋ก QR ์ฝ๋ ์์ญ ํ์
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
# ํ
์คํธ ์ ๋ณด ์์ฑ ๋ฐ ํ์
text = '%s (%s)' % (barcode_data, barcode_type)
cv2.putText(img, text, (x, y),
cv2.FONT_HERSHEY_SIMPLEX, 1,
(0, 255, 255), 2, cv2.LINE_AA)
# ํ๋ฉด์ ๊ฒฐ๊ณผ ํ์
cv2.imshow('img', img)
# ํค๋ณด๋ ์
๋ ฅ ์ฒ๋ฆฌ
key = cv2.waitKey(1)
if key == ord('q'): # 'q' ํค๋ก ์ข
๋ฃ
break
elif key == ord('s'): # 's' ํค๋ก ์ด๋ฏธ์ง ์ ์ฅ
i += 1
cv2.imwrite('c_%03d.jpg' % i, img)
# ๋ฆฌ์์ค ํด์
cap.release()
cv2.destroyAllWindows()
ํต์ฌ ๊ธฐ๋ฅ ๋ถ์
์น์บ ์ ์ด
์ด๊ธฐํ ๋ฐ ํด์ :
-
cv2.VideoCapture(0): ๊ธฐ๋ณธ ์นด๋ฉ๋ผ ์ฐ๊ฒฐ -
cap.read(): ํ๋ ์ ๋จ์๋ก ์ด๋ฏธ์ง ์ฝ๊ธฐ -
cap.release(): ์นด๋ฉ๋ผ ๋ฆฌ์์ค ํด์
QR ์ฝ๋ ์ธ์ ํ๋ก์ธ์ค
์ฒ๋ฆฌ ๋จ๊ณ:
-
์ปฌ๋ฌ ์ด๋ฏธ์ง๋ฅผ ๊ทธ๋ ์ด์ค์ผ์ผ๋ก ๋ณํ
-
pyzbar๋ก QR ์ฝ๋ ์ ๋ณด ์ถ์ถ
-
์ธ์๋ ๊ฐ QR ์ฝ๋์ ๋ํด ๋ฐ๋ณต ์ฒ๋ฆฌ
-
์๊ฐ์ ํ์ (์ฌ๊ฐํ, ํ ์คํธ) ์ถ๊ฐ
์ฌ์ฉ์ ์ธํฐํ์ด์ค
ํค๋ณด๋ ์ ์ด:
-
qํค: ํ๋ก๊ทธ๋จ ์ข ๋ฃ -
sํค: ํ์ฌ ํ๋ฉด ์ด๋ฏธ์ง ์ ์ฅ -
cv2.waitKey(1): ํค ์ ๋ ฅ ๋๊ธฐ (1ms)
๋ฌธ์ ํด๊ฒฐ
์ผ๋ฐ์ ์ธ ์ค๋ฅ
์นด๋ฉ๋ผ ์ ๊ทผ ์คํจ:
if not cap.isOpened():
print("์นด๋ฉ๋ผ๋ฅผ ์ด ์ ์์ต๋๋ค.")
exit()
QR ์ฝ๋ ์ธ์ ์๋จ:
-
์กฐ๋ช ์กฐ๊ฑด ํ์ธ
-
QR ์ฝ๋์ ์นด๋ฉ๋ผ ๊ฑฐ๋ฆฌ ์กฐ์
-
์ด๋ฏธ์ง ํ์ง ๋ฐ ํด์๋ ํ์ธ
์ฑ๋ฅ ์ต์ ํ
ํ๋ ์ ์ฒ๋ฆฌ ์ต์ ํ:
-
ํ์์ ์ด๋ฏธ์ง ํฌ๊ธฐ ์กฐ์ ์ผ๋ก ์ฒ๋ฆฌ ์๋ ํฅ์
-
ROI(Region of Interest) ์ค์ ์ผ๋ก ์ฒ๋ฆฌ ์์ญ ์ ํ
ํ์ฅ ๊ฐ๋ฅ์ฑ
์ถ๊ฐ ๊ธฐ๋ฅ ์์ด๋์ด
๋ฐ์ดํฐ ์ฒ๋ฆฌ:
-
QR ์ฝ๋ ๋ฐ์ดํฐ๋ฅผ ํ์ผ์ ์ ์ฅ
-
์ค๋ณต QR ์ฝ๋ ํํฐ๋ง
-
ํ์คํ ๋ฆฌ ๊ด๋ฆฌ
UI ๊ฐ์ :
-
์ธ์ ์ํ ํ์
-
์ค์ ๋ฉ๋ด ์ถ๊ฐ
-
๋ค์ํ ์๊ฐ์ ํจ๊ณผ
๋ค์ค ํฌ๋งท ์ง์:
-
๋ฐ์ฝ๋ ์ธ์ ์ถ๊ฐ
-
๋ค์ํ 2D ์ฝ๋ ์ง์
์ด ๊ฐ์ด๋๋ฅผ ํตํด OpenCV์ pyzbar๋ฅผ ์ฌ์ฉํ QR ์ฝ๋ ์ธ์ ์์คํ ์ ๋จ๊ณ์ ์ผ๋ก ๊ตฌ์ถํ ์ ์์ต๋๋ค.