Phân loại: - Tùy theo dung lượng thông tin, dạng thức thông tin được mã hóa cũng như mục đích sử dụng mà người ta chia ra làm rất nhiều lọai, trong đó các dạng thông dụng trên thị trườn
Trang 1ĐẠI HỌC QUỐC GIA TP.HỒ CHÍ MINH TRƯỜNG ĐẠI HỌC BÁCH KHOA KHOA ĐIỆN – ĐIỆN TỬ
BỘ MÔN TỰ ĐỘNG HÓA -o0o -
BÁO CÁO THỊ GIÁC MÁY
PROJECT 1: XỬ LÍ ẢNH CỜ CARO
GVHD: Thầy Nguyễn Trọng Tài
TPHCM, ngày 02 tháng 10 năm 2017
Trang 22
I Tổng quan:
1 Mã vạch là gì?
Mã vạch (barcode) là một phương pháp lưu trữ và truyền tải thông tin bằng một loại kí hiệu gọi là ký mã vạch (barcode symbology) Ký mã vạch là một tổ hợp các thanh đen và khoảng trắng giữa chúng để biểu diễn các mẫu kí tự
2 Phân loại:
- Tùy theo dung lượng thông tin, dạng thức thông tin được mã hóa cũng như mục đích sử dụng mà người ta chia ra làm rất nhiều lọai, trong đó các dạng thông dụng trên thị trường mà ta thấy gồm UPC, EAN, Code 39, Interleaved 2 of 5, Codabar và Code 128
- Ngoài ra, trong 1 số loại mã vạch người ta còn phát triển làm nhiều Version khác nhau, có mục đích sử dụng khác nhau
Thí dụ UPC có các version là UPC-A, UPC-B, UPC-C, UPC-D và UPC-E; EAN có các version EAN-8, EAN-13, EAN-14, Code 128 gồm Code 128 Auto, Code 128A, Code 128-B, Code 128-C
3 Một số loại barcode phổ biến:
Barcode 1D:
UPC (Universal Product Code)
UPC là 1 lọai ký hiệu mã hóa số được ngành công nghiệp thực phẩm ứng dụng vào năm 1973 Ngành công nghiệp thực phẩm đã phát triển hệ thống này nhằm gán mã số không trùng lặp cho từng sản phẩm Người ta sử dụng UPC như “giấy phép bằng số” cho các sản phẩm riêng lẽ
UPC gồm có 2 phần: phần mã vạch mà máy có thể đọc được và phần số
mà con người có thể đọc được
Số của UPC gồm 12 ký số, không bao gồm ký tự Đó là các mã số dùng
để nhận diện mỗi một sản phẩm tiêu dùng riêng biệt
EAN(European Article Number)
EAN là bước phát triển kế tiếp của UPC Về cách mã hóa nó cũng giống hệt như UPC nhưng về dung lượng nó gồm 13 ký số trong đó 2 hoặc 3 ký
số đầu tiên là ký số “mốc”, dùng để biểu thị cho nước xuất xứ Các ký số này chính là “mã quốc gia” của sản phẩm được cấp bởi Tổ chức EAN quốc tế (EAN International Organization) EAN này được gọi là EAN-13
để phân biệt với phiên bản EAN-8 sau này gồm 8 ký số
Vì EAN phát triển với mã quốc gia nên nó được sử dụng trên những sản phẩm lưu thông trên tòan cầu Các tiêu chuẩn của EAN do Tổ chức EAN quốc tế quản lý Ở Việt Nam, các doanh nghiệp muốn sử dụng được mã EAN trên sản phẩm của mình, phải là thành viên của Tổ chức Mã Số Mã Vạch Việt Nam, gọi tắt là EAN Việt Nam, để được cấp mã số doanh nghiệp
Trang 3 Barcode 2D:
Mã 2D có nghĩa là “hai chiều”, các mã vạch 2D chứa được nhiều thông tin quy ước chiều mã vạch hơn tuyến tính/ 1D Những quy ước mã vạch rộng lớn nhiều hơn dữ liệu được mã hóa Mã vạch 2D làm cho việc sử dụng theo phương thẳng đứng để chứa được nhiều dữ liệu hơn
Mã vạch lưu dữ liệu trong các vạch đứng hay chỉ theo chiều dọc, trong khi
đó mã 2D lưu dữ liệu trên cả chiều dọc lẫn chiều ngang Nếu mã vạch thông thường (UPC/EAN) có thể lưu đến 30 con số mà thường chúng ta thấy phổ biến là 13 chữ số thì mã 2D có thể lưu ít nhất là 7.089 chữ số Chỉ cần kích thước 1/10 của mã vạch, QR code có thể lưu cùng lượng thông tin
Barcode 2D phổ biến hiện nay là QRCode
4 Decode barcode
Trang 44
Trang 5II Phân tích đề tài:
Quét hình ảnh barcode về một sản phẩm, từ đó truy xuất tìm kiếm thông tin
về sản phẩm đó trên internet và hiển thị lên màn hình
Trong đề tài này nhóm dùng ngôn ngữ lập trình Python, thư viện OpenCv,
và một số thư viện liên quan như GUI, truy xuất dữ liệu web, …
Trang 6
6
III Giải thuật và xử lý bài toán:
1 Giải thuật:
YES
NO
NO
YES
NO
YES
START
SCAN_IMAGE
BARCODE AREA?
SAVE BARCODE AREA
DETECT BARCODE?
CREAT GUI AND SHOW
END
TAKE INFORMATION FROM WEB
OFF?
SHUTDOWN?
Trang 72 Code:
2.1 Import thư viện:
import numpy as np
import cv2
import zbar
import urllib2
import webbrowser as web
import qrtools as qrt
from bs4 import BeautifulSoup
import requests
from lxml import html
import ttk
import Tkinter as tk
from PIL import ImageTk, Image
2.2 Hàm barcode Scan
def _Scan(image):
try:
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gradX = cv2.Sobel(gray, ddepth = cv2.CV_32F, dx = 1, dy = 0, ksize =
-1)
gradY = cv2.Sobel(gray, ddepth = cv2.CV_32F, dx = 0, dy = 1, ksize =
-1)
gradient = cv2.subtract(gradX, gradY)
gradient = cv2.convertScaleAbs(gradient)
blurred = cv2.medianBlur(gradient,5)
_, thresh = cv2.threshold(blurred, 127, 255, cv2.THRESH_BINARY)
# construct a closing kernel and apply it to the thresholded image
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 7)) #creat mat ones(21,7)
closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
# perform a series of erosions and dilations
closed = cv2.erode(closed, None, iterations = 4)
closed = cv2.dilate(closed, None, iterations = 4)
img, cnts, hierarchy = cv2.findContours(closed.copy(),
cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
c = sorted(cnts, key = cv2.contourArea, reverse = True)[0]
# compute the rotated bounding box of the largest contour
Trang 88
rect = cv2.minAreaRect(c)
box = np.int0(cv2.boxPoints(rect))
box_x = []
box_y = []
for i in range (0 4 1):
box_x.append(box[i][1])
box_x = np.sort(box_x)
for i in range (0 4 1):
box_y.append(box[i][0])
box_y = np.sort(box_y)
# print box_x
# print box_y
cv2.drawContours(image, [box], -1, (0, 255, 0), 3)
cv2.imshow('qr-code',image)
img_1 = np.zeros((box_x[3]-box_x[0],box_y[3]-box_y[0],3), np.uint8) img_1 = image[box_x[0]:box_x[3],box_y[0]:box_y[3]]
resized_image = cv2.resize(img_1, (300, 150))
# cv2.imshow("image_1", resized_image)
his= cv2.cvtColor(resized_image, cv2.COLOR_BGR2GRAY)
his = cv2.equalizeHist(his)
# print 'b'
cv2.imshow("image_2", resized_image)
cv2.imwrite('qrcode.png',his)
qr.decode('qrcode.png')
except:
# print 'a'
[]
return qr.data
2.3 Hàm truy xuất dữ liệu web:
def _Product(code):
No_Pro = 1
Key =[]
Value = []
Store =[]
ProductInfo =[]
Price =[]
Update =[]
Name_P = ''
Trang 9try:
Web_name = 'http://www.upcitemdb.com/upc/'
# print Web_name
# number = code
quote_page = Web_name + str(code)
print quote_page
# web.open(quote_page)
page = urllib2.urlopen(quote_page)
soup = BeautifulSoup(page, 'html.parser')
# soup = BeautifulSoup(page, 'lxml') #faster
shopping_Info = soup.find_all('tr')
# print len(shopping_Info)
for a in range( ,len(shopping_Info),1):
name = shopping_Info[a].find_all('td')
Store.append( name[0].text.strip())
ProductInfo.append(name[1].text.strip())
Price.append(name[2].text.strip())
Update.append(name[3].text.strip())
More_Info_Key = soup.find_all('dt')
More_Info_Value = soup.find_all('dd')
len_x = len(More_Info_Key) -1
for j in range( ,len_x,1):
Key.append(More_Info_Key[j].text.strip())
Value.append(More_Info_Value[j].text.strip())
Name_P = soup.find('b').text.strip()
# print 'Name: ', Name_Pro
# print 'Key: ', Key
# print 'Value: ', Value
# print 'Store: ', Store
# print 'Info: ', ProductInfo
# print 'Time: ', Update
# print name_box
# webbrowser.open_new(quote_page)
# i= i+1;
except:
No_Pro = 0
[]
# print 'This product is not available on our website'
return No_Pro, Name_P, Key, Value, Store, ProductInfo,Price, Update
Trang 1010
2.4 Hàm Main và hiển thị GUI:
cap = cv2.VideoCapture(0)
i = 0
r = tk.Tk() #tao GUI
r.title('BarCode Application')
number=0
code_1 =0
qr = qrt.QR()
lstLabelKey = []
lstLabelValue = []
lstStore =[]
lstProductInfo=[]
lstPrice=[]
lstUpdate=[]
lbKey = dict()
lbValue = dict()
lbStore = dict()
lbProductInfo = dict()
lbPrice = dict()
lbUpdate = dict()
fr = dict()
Name_P = []
Key=[]
Name=[]
Store=[]
ProductInfo=[]
Price=[]
Update=[]
while( ):
while(i==0):
# print 'b'
res, image = cap.read()
code = _Scan(image)
if code == 'NULL' or code == code_1:
[]
else:
code_1 = str(code)
No_Pro, Name_Product, Key, Name, Store, ProductInfo, Price, Update = _Product(code_1)
Trang 11i=1
cv2.destroyWindow('qr-code')
break
# print Update
# print 'OK'
# image = cv2.imread('IMG_1092.png')
# cv2.imshow("image1", image)
if cv2.waitKey(5) == ord('q'):
i=1
cv2.destroyWindow('qr-code')
break
if cv2.waitKey(5) == 27:
i=2
break
while(i==1):
if No_Pro == 0:
title = ttk.Label(r, text = 'BarCode Result',relief=tk.GROOVE, width
= 60, anchor = tk.CENTER, foreground = 'maroon',padding = 5)
title.grid(column = 0, row = 0)
txt = 'This product (' + str(code) + ') is not available on our website'
title1 = ttk.Label(r, text = txt ,relief=tk.GROOVE, width = 60,
anchor = tk.CENTER, foreground = 'maroon',padding = 5)
title1.grid(column = 0, row = 1)
fr['Frame2'] = ttk.LabelFrame(r, text = 'Barcode_img' )
fr['Frame2'].grid(column =0 , row = 2)
img = ImageTk.PhotoImage(Image.open('qrcode.png'))
panel= tk.Label(fr['Frame2'], image= img, pady = 20)
panel.grid()
tk.mainloop()
# r.destroy()
# print 'This product is not available on our website'
else:
for i in range(len(Key)):
lstLabelKey.append('Key' + str(i))
# print lstLabel[i]/
for i in range(len(Name)):
lstLabelValue.append('Value' + str(i))
for i in range( ):
lstStore.append('Store' + str(i))
lstProductInfo.append('product' + str(i))
lstPrice.append('price' + str(i))
lstUpdate.append('Update' + str(i))
Trang 1212
title = ttk.Label(r, text = 'BarCode Result',relief=tk.GROOVE, width
= 165, anchor = tk.CENTER, foreground = 'maroon',padding = 5)
title.grid(column = 0, row = 0)
pd = ttk.Label(r, text = Name_Product ,relief=tk.GROOVE, width =
165, anchor = tk.CENTER, foreground = 'blue',padding = 5)
pd.grid(column = 0, row = 1)
fr['Frame4'] = ttk.Frame(r, padding =10 )
fr['Frame4'].grid(column =0 , row = 2 )
fr['Frame1'] = tk.LabelFrame(fr['Frame4'], text = 'Infomation',
foreground = 'blue', padx= 10, pady = 10 )
fr['Frame1'].grid(column =0 , row = 0 )
for i,u,v,z in zip(lstLabelKey,lstLabelValue,Key,Name):
lbKey[i] = tk.Label(fr['Frame1'], text = v, relief=tk.RIDGE,
anchor = tk.W, width = 25, height = 1)
lbValue[u] = tk.Label(fr['Frame1'], text = z, relief=tk.RIDGE,
anchor = tk.CENTER, width = 20, height = 1)
for i,u,v,z in
zip(lstLabelKey,lstLabelValue,range(len(Key)),range(len(Name))):
lbKey[i].grid(column= , row = v )
lbValue[u].grid(column= , row = z )
fr['Frame2'] = ttk.LabelFrame(fr['Frame4'], text = 'Barcode_img' ) fr['Frame2'].grid(column =1 , row = 0)
img = ImageTk.PhotoImage(Image.open('qrcode.png'))
panel= tk.Label(fr['Frame2'], image= img, pady = 20)
panel.grid()
fr['Frame3'] = ttk.LabelFrame(r, text = 'Shopping Info' )
fr['Frame3'].grid(column =0 , row = 3)
txtStore = ttk.Label(fr['Frame3'], text = 'Stores'
,relief=tk.GROOVE, width = 25, anchor = tk.CENTER, foreground = 'blue')
txtStore.grid(column = 0, row = 0)
txtProduct = ttk.Label(fr['Frame3'], text = 'Product Info'
,relief=tk.GROOVE,width = 90, anchor = tk.CENTER, foreground = 'blue')
txtProduct grid(column = 1, row = 0)
Trang 13txtPrice = ttk.Label(fr['Frame3'], text = 'Price' ,relief=tk.GROOVE,
width = 25, anchor = tk.CENTER, foreground = 'blue')
txtPrice.grid(column = 2, row = 0)
txtUpdate = ttk.Label(fr['Frame3'], text = 'Update'
,relief=tk.GROOVE, width = 25, anchor = tk.CENTER, foreground = 'blue')
txtUpdate.grid(column = 3, row = 0)
# print 'a'
for a,b,c,d,x,y,z,t in
zip(lstStore,lstProductInfo,lstPrice,lstUpdate,Store,ProductInfo,Price,Update): # print 'b'
lbStore[a] = ttk.Label(fr['Frame3'], text = x, relief=tk.GROOVE,
anchor = tk.W, width = 25)
lbProductInfo[b] = ttk.Label(fr['Frame3'], text = y,
relief=tk.GROOVE, anchor = tk.CENTER, width = 90)
lbPrice[c] = ttk.Label(fr['Frame3'], text = z, relief=tk.GROOVE,
anchor = tk.CENTER, width = 25)
lbUpdate[d] = ttk.Label(fr['Frame3'], text = t,
relief=tk.GROOVE, anchor = tk.CENTER, width = 25)
for a,b,c,d,x in
zip(lstStore,lstProductInfo,lstPrice,lstUpdate,range( , )):
lbStore[a].grid(column = 0, row = x)
lbProductInfo[b].grid(column = 1, row = x)
lbPrice[c].grid(column = 2, row = x)
lbUpdate[d].grid(column = 3, row = x)
tk.mainloop()
# r.destroy()
# if cv2.waitKey(5) == ord('q'):
r = tk.Tk() #tao GUI
r.title('BarCode Application')
code = 0
code_1 =0
qr = qrt.QR()
lstLabelKey = []
lstLabelValue = []
lstStore =[]
lstProductInfo=[]
lstPrice=[]
lstUpdate=[]
Trang 1414
lbKey = dict()
lbValue = dict()
lbStore = dict()
lbProductInfo = dict() lbPrice = dict()
lbUpdate = dict()
fr = dict()
Name_P = []
Key=[]
Name=[]
Store=[]
ProductInfo=[]
Price=[]
Update=[]
cv2.destroyWindow('image0') i=0
break
if i ==2:
break
Trang 15IV Kết quả:
Barcode tìm được sản phẩm:
Barcode không tìm ra sản phầm:
Trang 1616
V Các lệnh thực thi quan trọng:
1 Cv2.Sobel:
2 Cv2.medianBlur:
3 Cv2.threshold:
4 Cv2.getStructuringElement:
5 Cv2.morphologyEx:
6 Cv2.findContours:
7 Cv2.equalizeHist: