def segmentation(self, LpRegion): """ Hàm phân đoạn ảnh :param LpRegion: :return: """ # Áp dụng thresh để trích xuất vùng biển số V = cv2.split(cv2.cvtColor(LpRegion, cv2.COLOR_BGR2HSV))[2] # Phân ngưỡng bằng adaptive threshold retval, threshold = cv2.threshold(V, 128, 255, cv2.THRESH_BINARY) T = threshold_local(V, 15, offset=10, method="gaussian") thresh = (V > T).astype("uint8") * 255 # Chuyển đổi pixel đen của chữ số thành pixel trắng thresh = cv2.bitwise_not(thresh) # Resize ảnh thresh với chiều rộng = 400px thresh = imutils.resize(thresh, width=400) # thresh = cv2.medianBlur(thresh, 5) # Xóa nhiễu bằng thuật toán opening (erode => dilate) kernel = np.ones((2, 2), np.uint8) thresh = cv2.erode(thresh, kernel) thresh = cv2.dilate(thresh, kernel) # Thực hiện thuật toán connected components analysis labels = measure.label(thresh, connectivity=2, background=0) # Lặp qua các thành phần duy nhất for label in np.unique(labels): # if this is background label, ignore it if label == 0: continue # Khởi tạo mặt nạ chứa vị trí của các ký tự ứng viên mask = np.zeros(thresh.shape, dtype="uint8") mask[labels == label] = 255 # Tìm contours từ mặt nạ contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if len(contours) > 0: contour = max(contours, key=cv2.contourArea) (x, y, w, h) = cv2.boundingRect(contour) # Xác định ký tự aspectRatio = w / float(h) solidity = cv2.contourArea(contour) / float(w * h) heightRatio = h / float(LpRegion.shape[0]) if 0.1 < aspectRatio < 1.0 and solidity > 0.1 and 0.35 < heightRatio < 2.0: # Trích xuất các ký tự candidate = np.array(mask[y:y + h, x:x + w]) square_candidate = convert2Square(candidate) square_candidate = cv2.resize(square_candidate, (28, 28), cv2.INTER_AREA) square_candidate = square_candidate.reshape((28, 28, 1)) self.candidates.append((square_candidate, (y, x)))
def segmentation(self, LpRegion, name): # apply thresh to extracted licences plate V = cv2.split(cv2.cvtColor(LpRegion, cv2.COLOR_BGR2HSV))[2] # adaptive threshold T = threshold_local(V, 15, offset=10, method="gaussian") thresh = (V > T).astype("uint8") * 255 cv2.imwrite("output/lp/{}_step2_1.png".format(name), thresh) # convert black pixel of digits to white pixel thresh = cv2.bitwise_not(thresh) cv2.imwrite("output/lp/{}_step2_2.png".format(name), thresh) thresh = imutils.resize(thresh, width=400) thresh = cv2.medianBlur(thresh, 5) cv2.imwrite("output/lp/{}_step2_3.png".format(name), thresh) # connected components analysis labels = measure.label(thresh, connectivity=2, background=0) # loop over the unique components for label in np.unique(labels): # if this is background label, ignore it if label == 0: continue # init mask to store the location of the character candidates mask = np.zeros(thresh.shape, dtype="uint8") mask[labels == label] = 255 # find contours from mask _, contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if len(contours) > 0: contour = max(contours, key=cv2.contourArea) (x, y, w, h) = cv2.boundingRect(contour) # rule to determine characters aspectRatio = w / float(h) solidity = cv2.contourArea(contour) / float(w * h) heightRatio = h / float(LpRegion.shape[0]) if 0.1 < aspectRatio < 1.0 and solidity > 0.1 and 0.35 < heightRatio < 2.0: # extract characters candidate = np.array(mask[y:y + h, x:x + w]) square_candidate = convert2Square(candidate) square_candidate = cv2.resize(square_candidate, (28, 28), cv2.INTER_AREA) cv2.imwrite( './characters/' + str(x) + "_" + str(y) + ".png", cv2.resize(square_candidate, (56, 56), cv2.INTER_AREA)) square_candidate = square_candidate.reshape((28, 28, 1)) self.candidates.append((square_candidate, (y, x)))
def segmentation(self, LpRegion): LpRegion = self.clean_border(LpRegion) # cv2.imshow("edge", edged) V = cv2.split(cv2.cvtColor(LpRegion, cv2.COLOR_BGR2HSV))[2] # adaptive threshold T = threshold_local(V, 15, offset=10, method="gaussian") thresh = (V > T).astype("uint8") * 255 # convert black pixel of digits to white pixel thresh = cv2.bitwise_not(thresh) thresh = imutils.resize(thresh, width=400) thresh = clear_border(thresh) # cv2.imwrite("step2_2.png", thresh) cv2.imshow("thresh", thresh) cv2.waitKey(0) cv2.destroyAllWindows() # try: # lines = cv2.HoughLinesP(image=thresh,rho=1,theta=np.pi/180, threshold=200,lines=np.array([]), minLineLength=200,maxLineGap=20) # angle = 0 # num = 0 # thresh = cv2.cvtColor(thresh, cv2.COLOR_GRAY2BGR) # for line in lines: # my_degree = math.degrees(math.atan2(line[0][3]-line[0][1], line[0][2]-line[0][0])) # if -45 < my_degree < 45: # angle += my_degree # num += 1 # cv2.line(thresh, (line[0][0], line[0][1]), (line[0][2], line[0][3]), (255, 0, 0)) # angle /= num # cv2.imshow("draw", thresh) # cv2.waitKey(0) # cv2.destroyAllWindows() # # cv2.imwrite("draw.png", thresh) # # Rotate image to deskew # (h, w) = thresh.shape[:2] # center = (w // 2, h // 2) # M = cv2.getRotationMatrix2D(center, angle, 1.0) # thresh = cv2.warpAffine(thresh, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE) # except: # pass # edges = cv2.Canny(thresh,100,200) # thresh = cv2.medianBlur(thresh, 5) # cv2.imshow("thresh", edges) # cv2.waitKey(0) # cv2.destroyAllWindows() # cv2.imwrite("thresh.png", thresh) # connected components analysis labels = measure.label(thresh, connectivity=2, background=0) # loop over the unique components for label in np.unique(labels): # if this is background label, ignore it if label == 0: continue # init mask to store the location of the character candidates mask = np.zeros(thresh.shape, dtype="uint8") mask[labels == label] = 255 # find contours from mask contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if len(contours) > 0: contour = max(contours, key=cv2.contourArea) (x, y, w, h) = cv2.boundingRect(contour) # rule to determine characters aspectRatio = w / float(h) solidity = cv2.contourArea(contour) / float(w * h) heightRatio = h / float(LpRegion.shape[0]) if h * w > MIN_PIXEL_AREA and 0.25 < aspectRatio < 1.0 and solidity > 0.2 and 0.35 < heightRatio < 2.0: # extract characters candidate = np.array(mask[y:y + h, x:x + w]) square_candidate = convert2Square(candidate) square_candidate = cv2.resize(square_candidate, (28, 28), cv2.INTER_AREA) # cv2.imwrite('./characters/' + str(y) + "_" + str(x) + ".png", cv2.resize(square_candidate, (56, 56), cv2.INTER_AREA)) square_candidate = square_candidate.reshape((28, 28, 1)) # cv2.imshow("square_candidate", square_candidate) # cv2.waitKey(0) # cv2.destroyAllWindows() self.candidates.append((square_candidate, (y, x)))