def sobelFrtSearch(self, srcImage): src_threshold = self.sobelOper(srcImage, self.m_GaussianBlurSize, self.m_MorphSizeWidth, self.m_MorphSizeHeight) if self.debug: imageTools.imshow("src_threshold", src_threshold) _, contours, _ = cv2.findContours( src_threshold, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # all pixels of each contours outRects = [] testImage = srcImage.copy() mask = np.zeros((srcImage.shape[0], srcImage.shape[1], 1), dtype=np.uint8) for itc in contours: # 中心(x,y), (宽,高), 旋转 角度 rotationrect = cv2.minAreaRect(itc) rect = RotationRect(rotationrect) if self.common.verifySizes(rect): isFormRect, safeBoundRect = imageTools.calcSafeRect( rotationrect, srcImage) if not isFormRect: continue if self.debug: cv2.drawContours(mask, [itc], -1, (255, 255, 255), -1) targetContour = cv2.bitwise_and(testImage, testImage, mask=mask) imageTools.imshow("target contour", targetContour) outRects.append(safeBoundRect) return outRects
def isdeflection(self, img, angle): if self.debug: imageTools.imshow("img", img) nRows = img.shape[0] nCols = img.shape[1] #assert(in.channels() == 1) comp_index = [0, 0, 0] len = [0, 0, 0] comp_index[0] = nRows // 4 comp_index[1] = nRows // 4 * 2 comp_index[2] = nRows // 4 * 3 for i in range(4): index = comp_index[i] p = img[index] j = 0 value = 0 while 0 == value and j < nCols: value = int(p[j]) j = j + 1 len[i] = j maxlen = max(len[2], len[0]) minlen = min(len[2], len[0]) difflen = abs(len[2] - len[0]) PI = 3.14159265 g = math.tan(angle * PI / 180.0) if maxlen - len[1] > nCols / 32 or len[1] - minlen > nCols / 32: slope_can_1 = (len[2] - len[0]) / comp_index[1] slope_can_2 = (len[1] - len[0]) / comp_index[0] slope_can_3 = (len[2] - len[1]) / comp_index[0] slope = slope_can_1 if abs(slope_can_1 - g) <= abs(slope_can_2 - g) else slope_can_2 return (True, slope) else: slope = 0 return (False, slope)
def deleteNotArea(self, inmat, color=COLOR.UNKNOWN): input_grey = cv2.cvtColor(inmat, cv2.COLOR_BGR2GRAY) w = inmat.shape[1] h = inmat.shape[0] tmpMat = imageTools.crop(inmat, h * 0.1, w * 0.15, w * 0.7, h * 0.7) plateType = COLOR.UNKNOWN if COLOR.UNKNOWN == color: plateType = imageTools.getPlateType(tmpMat, True) else: plateType = color img_threshold = None if COLOR.BLUE == plateType: img_threshold = input_grey.copy() tmp = imageTools.crop(input_grey, w * 0.15, h * 0.15, w * 0.7, h * 0.7) if self.debug: imageTools.imshow("tmp", tmp) threadHoldV = imageTools.thresholdOtsu(tmp) _, img_threshold = cv2.threshold(input_grey, threadHoldV, 255, cv2.THRESH_BINARY) if self.debug: imageTools.imshow("img_threshold", img_threshold) elif COLOR.YELLOW == plateType: img_threshold = input_grey.copy() tmp = imageTools.crop(input_grey, w * 0.1, h * 0.1, w * 0.8, h * 0.8) threadHoldV = imageTools.thresholdOtsu(tmp) _, img_threshold = cv2.threshold(input_grey, threadHoldV, 255, cv2.THRESH_BINARY_INV) if self.debug: imageTools.imshow("img_threshold", img_threshold) else: _, img_threshold = cv2.threshold( input_grey, 10, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY) top = 0 bottom = img_threshold.shape[0] - 1 flg, img_threshold = imageTools.clearLiuDing(img_threshold) flg, posLeft, posRight = imageTools.bFindLeftRightBound1(img_threshold) if flg: inmat = imageTools.crop(inmat, posLeft, top, w - posLeft, bottom - top) if self.debug: imageTools.imshow("inmat", inmat) return inmat
def affine(self, img, slope): if self.debug: imageTools.imshow("img", img) height = img.shape[0] width = img.shape[1] xiff = abs(slope) * height plTri = [] dstTri = [] if slope > 0: # right, new position is xiff/2 plTri.append([0, 0]) plTri.append([width - xiff - 1, 0]) plTri.append([0 + xiff, height - 1]) dstTri.append([xiff / 2, 0]) dstTri.append([width - 1 - xiff // 2, 0]) dstTri.append([xiff / 2, height - 1]) else: # left, new position is -xiff/2 plTri.append([0 + xiff, 0]) plTri.append([width - 1, 0]) plTri.append([0, height - 1]) dstTri.append([xiff / 2, 0]) dstTri.append([width - 1 - xiff + xiff // 2, 0]) dstTri.append([xiff / 2, height - 1]) plTri = np.float32(plTri) dstTri = np.float32(dstTri) warp_mat = cv2.getAffineTransform(plTri, dstTri) affine_size = (height, width) if img.shape[0] > constants.HEIGHT or img.shape[1] > constants.WIDTH: affine_mat = cv2.warpAffine(img, warp_mat, affine_size, cv2.INTER_AREA) else: affine_mat = cv2.warpAffine(img, warp_mat, affine_size, cv2.INTER_CUBIC) return affine_mat
def sobelSecSearch(self, bound, x, y): bound_threshold = self.sobelOper(bound, 3, 10, 3) if self.debug: imageTools.imshow("bound_threshold", bound_threshold) _, contours, _ = cv2.findContours( bound_threshold, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # all pixels of each contours outRects = [] for itc in contours: # 中心(x,y), (宽,高), 旋转 角度 rotationrect = cv2.minAreaRect(itc) rect = RotationRect(rotationrect) if self.common.verifySizes(rect): refcenter = (rect.center_x + x, rect.center_y + y) refroi = (refcenter, rect.size, rect.angle) outRects.append(refroi) return outRects
def sobelSecSearchPart(self, bound, x, y): outRects = [] bound_threshold = self.sobelOper(bound, 3, 6, 2) tempBoundThread = imageTools.clearLiuDingOnly(bound_threshold) flg, posLeft, posRight = imageTools.bFindLeftRightBound( tempBoundThread) if flg: # find left and right bounds to repair if posRight != 0 and posLeft != 0 and posLeft < posRight: row = int(bound_threshold.shape[0] * 0.5) start = posLeft + int(bound_threshold.shape[0] * 0.1) bound_threshold[row, start:posRight - 4] = 255 if self.debug: imageTools.imshow("bound_threshold", bound_threshold) # remove the left and right boundaries bound_threshold[:, posLeft] = 0 bound_threshold[:, posRight] = 0 if self.debug: imageTools.imshow("bound_threshold", bound_threshold) _, contours, _ = cv2.findContours(bound_threshold, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) for itc in contours: # 中心(x,y), (宽,高), 旋转 角度 rotationrect = cv2.minAreaRect(itc) rect = RotationRect(rotationrect) if self.common.verifySizes(rect): refcenter = (rect.center_x + x, rect.center_y + y) refroi = (refcenter, rect.size, rect.angle) outRects.append(refroi) return outRects
def sobelOper(self, srcImage, blurSize, morphW, morphH): mat_blur = cv2.GaussianBlur(srcImage, (blurSize, blurSize), 0, 0, cv2.BORDER_DEFAULT) if self.debug: imageTools.imshow("mat_blur", mat_blur) if mat_blur.ndim == 3: mat_gray = cv2.cvtColor(mat_blur, cv2.COLOR_RGB2GRAY) else: mat_gray = mat_blur if self.debug: imageTools.imshow("mat_gray", mat_gray) scale = constants.SOBEL_SCALE delta = constants.SOBEL_DELTA ddepth = constants.SOBEL_DDEPTH #grad_x = cv2.Sobel(mat_gray, ddepth, 1, 0, 3, scale, delta, cv2.BORDER_DEFAULT) grad_x = cv2.Sobel(mat_gray, ddepth, 1, 0, 3) # 将RealSense提取的深度图片进行显示时,由于是16位图片,想将图片转化成为8位图形进行显示 abs_grad_x = cv2.convertScaleAbs(grad_x) if self.debug: imageTools.imshow("abs_grad_x", abs_grad_x) grad = cv2.addWeighted(abs_grad_x, constants.SOBEL_X_WEIGHT, 0, 0, 0) _, mat_threshold = cv2.threshold(grad, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY) if self.debug: imageTools.imshow("mat_threshold", mat_threshold) element = cv2.getStructuringElement(cv2.MORPH_RECT, (morphW, morphH)) mat_threshold = cv2.morphologyEx(mat_threshold, cv2.MORPH_CLOSE, element) if self.debug: imageTools.imshow("mat_threshold after close", mat_threshold) return mat_threshold
def colorSearch(self, srcImage, color): # width is important to the final results; color_morph_width = 10 color_morph_height = 2 match_grey = imageTools.colorMatch(srcImage, color, False) if self.debug: imageTools.imshow("match_grey", match_grey) _, src_threshold = cv2.threshold(match_grey, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY) if self.debug: imageTools.imshow("src_threshold", src_threshold) element = cv2.getStructuringElement( cv2.MORPH_RECT, (color_morph_width, color_morph_height)) src_threshold = cv2.morphologyEx(src_threshold, cv2.MORPH_CLOSE, element) if self.debug: imageTools.imshow("threshold", src_threshold) out = src_threshold.copy() _, contours, _ = cv2.findContours( src_threshold, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # all pixels of each contours outRects = [] testImage = srcImage.copy() mask = np.zeros((srcImage.shape[0], srcImage.shape[1], 1), dtype=np.uint8) for itc in contours: # 中心(x,y), (宽,高), 旋转 角度 rotationrect = cv2.minAreaRect(itc) rect = RotationRect(rotationrect) if self.common.verifySizes(rect): outRects.append(rotationrect) if self.debug: cv2.drawContours(mask, [itc], -1, (255, 255, 255), -1) targetContour = cv2.bitwise_and(testImage, testImage, mask=mask) imageTools.imshow("target contour", targetContour) return (out, outRects)
def rotation(self, img, rect_size, center, angle): in_large = None if img.ndim < 3: in_large = np.zeros( (int(img.shape[0] * 1.5), int(img.shape[1] * 1.5)), np.uint8) else: in_large = np.zeros((int( img.shape[0] * 1.5), int(img.shape[1] * 1.5), img.shape[2]), np.uint8) x = in_large.shape[1] / 2 - center[ 0] if in_large.shape[1] / 2 - center[0] > 0 else 0 x = int(x) y = in_large.shape[0] / 2 - center[ 1] if in_large.shape[0] / 2 - center[1] > 0 else 0 y = int(y) width = img.shape[1] if x + img.shape[1] < in_large.shape[ 1] else in_large.shape[1] - x height = img.shape[0] if y + img.shape[0] < in_large.shape[ 0] else in_large.shape[0] - y if width != img.shape[1] or height != img.shape[0]: return (False, None) imageRoi = imageTools.crop(in_large, x, y, width, height) imageRoi = cv2.addWeighted(imageRoi, 0, img, 1, 0) #center_diff = (img.shape[1] / 2, img.shape[0] / 2) new_center = (in_large.shape[1] // 2, in_large.shape[0] // 2) rot_mat = cv2.getRotationMatrix2D(new_center, angle, 1) if self.debug: imageTools.imshow("in_copy", in_large) mat_rotated = cv2.warpAffine(in_large, rot_mat, (in_large.shape[1], in_large.shape[0]), cv2.INTER_CUBIC) if self.debug: imageTools.imshow("mat_rotated", mat_rotated) img_crop = cv2.getRectSubPix(mat_rotated, (rect_size[0], rect_size[1]), new_center) if self.debug: imageTools.imshow("img_crop", img_crop) return (True, img_crop)
for bound_rect in bound_rects: bound_rect_x, bound_rect_y, bound_rect_width, bound_rect_height = bound_rect x = bound_rect_x if bound_rect_x > 0 else 0 y = bound_rect_y if bound_rect_y > 0 else 0 width = bound_rect_width if x + bound_rect_width < srcImage.shape[ 1] else srcImage.shape[1] - x height = bound_rect_height if y + bound_rect_height < srcImage.shape[ 0] else srcImage.shape[0] - y bound_mat = imageTools.crop(srcImage, x, y, width, height) rects_sobel = self.sobelSecSearch(bound_mat, x, y) if len(rects_sobel) > 0: rects_sobel_all.extend(rects_sobel) src_b = self.sobelOper(srcImage, 3, 10, 3) plates = self.common.deskew(srcImage, src_b, rects_sobel_all) if len(plates) > 0: candPlates.extend(plates) return candPlates if __name__ == "__main__": image_dir = '../dataset/Plate_Image/' locater = PlateSobelLocate(True) for filename in os.listdir(image_dir): if filename.endswith(".jpg"): #704004834828 print(filename) fileFullPath = os.path.join(image_dir, filename) img = cv2.imread(fileFullPath) imageTools.imshow("img", img) locater.plateLocate(img)
def deskew(self, srcImage, src_b, inRects, useDeteleArea=False, color=COLOR.UNKNOWN): outPlate = [] for roi_rect in inRects: rect = RotationRect(roi_rect) roi_ratio = rect.width / rect.height roi_angle = rect.angle roi_rect_size = rect.size if roi_ratio < 1: roi_angle = 90 + roi_angle rect.width, rect.height = rect.height, rect.width # m_angle=60 if (roi_angle - self.m_angle) < 0 and (roi_angle + self.m_angle) > 0: isFormRect, safeBoundRect = imageTools.calcSafeRect( roi_rect, srcImage) if not isFormRect: continue (x, y, w, h) = safeBoundRect bound_mat = imageTools.crop(srcImage, x, y, w, h) bound_mat_b = imageTools.crop(src_b, x, y, w, h) if self.debug: imageTools.imshow("bound_mat", bound_mat) imageTools.imshow("bound_mat_b", bound_mat_b) roi_ref_center = (rect.center_x - safeBoundRect[0], rect.center_y - safeBoundRect[1]) deskew_mat = bound_mat if (roi_angle - 5 < 0 and roi_angle + 5 > 0 ) or 90.0 == roi_angle or -90.0 == roi_angle: deskew_mat = bound_mat else: flg, rotated_mat = self.rotation(bound_mat, roi_rect_size, roi_ref_center, roi_angle) if not flg: continue flg, rotated_mat_b = self.rotation(bound_mat_b, roi_rect_size, roi_ref_center, roi_angle) if not flg: continue # we need affine for rotatioed image if self.debug: imageTools.imshow("1roated_mat", rotated_mat) imageTools.imshow("rotated_mat_b", rotated_mat_b) flg, roi_slope = self.isdeflection(rotated_mat_b, roi_angle) if flg: deskew_mat = self.affine(rotated_mat, roi_slope) else: deskew_mat = rotated_mat plate_size = (constants.HEIGHT, constants.WIDTH) #haitungaga add,affect 25% to full recognition. if useDeteleArea: deskew_mat = self.deleteNotArea(deskew_mat, color) if deskew_mat.shape[1] * 1.0 / deskew_mat.shape[ 0] > 2.3 and deskew_mat.shape[ 1] * 1.0 / deskew_mat.shape[0] < 6: if deskew_mat.shape[ 1] >= constants.WIDTH or deskew_mat.shape[ 0] >= constants.HEIGHT: plate_mat = cv2.resize(deskew_mat, plate_size, 0, 0, cv2.INTER_AREA) else: plate_mat = cv2.resize(deskew_mat, plate_size, 0, 0, cv2.INTER_CUBIC) plate = Plate() plate.setPlatePos(roi_rect) plate.setPlateMat(plate_mat) if color != COLOR.UNKNOWN: plate.setPlateColor(color) outPlate.append(plate) return outPlate