일련의 이미지에서 텍스트를 식별하고 싶습니다. 흰색과 검은 색 텍스트가 모두있는 이미지가 있습니다.
otsu thresholding을 사용하여 이미지를 이진화했습니다.
윤곽선을 식별하고 텍스트가 아닌 영역을 제거한 후 필요한 텍스트 영역을 식별했습니다.
모든 텍스트가 흰색으로 필요합니다. 그러나 나는 그것을하는 방법을 모른다. 비트 연산자를 사용하려고 생각했지만 방법을 찾을 수 없습니다. 누군가 나를 도와 줄 수 있습니까?
예상 출력 :
import cv2
import numpy as np
def process(img):
# read image
img_no = str(img)
rgb = cv2.imread(img_no + '.jpg')
# cv2.imshow('original', rgb)
# convert image to grayscale
gray = cv2.cvtColor(rgb, cv2.COLOR_BGR2GRAY)
_, bw_copy = cv2.threshold(gray, 0.0, 255.0, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
# bilateral filter
blur = cv2.bilateralFilter(gray, 5, 75, 75)
# cv2.imshow('blur', blur)
# morphological gradient calculation
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
grad = cv2.morphologyEx(blur, cv2.MORPH_GRADIENT, kernel)
# cv2.imshow('gradient', grad)
# binarization
_, bw = cv2.threshold(grad, 0.0, 255.0, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
# cv2.imshow('otsu', bw)
# closing
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 1))
closed = cv2.morphologyEx(bw, cv2.MORPH_CLOSE, kernel)
# cv2.imshow('closed', closed)
# finding contours
contours, hierarchy = cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
mask = np.zeros(closed.shape, dtype=np.uint8)
mask1 = np.zeros(bw_copy.shape, dtype=np.uint8)
for idx in range(len(contours)):
x, y, w, h = cv2.boundingRect(contours[idx])
mask[y:y + h, x:x + w] = 0
area = cv2.contourArea(contours[idx])
aspect_ratio = float(w) / h
cv2.drawContours(mask, contours, idx, (255, 255, 255), -1)
r = float(cv2.countNonZero(mask[y:y + h, x:x + w])) / (w * h)
# identify region of interest
if r > 0.34 and 0.52 < aspect_ratio < 13 and area > 145.0:
cv2.drawContours(mask1, [contours[idx]], -1, (255, 255, 255), -1)
result = cv2.bitwise_and(bw_copy, mask1)
cv2.imshow('result', result)
print(img_no + " Done")
cv2.waitKey()
새로운 이미지
수락 된 답변은이 사진에서 작동하지 않습니다.
언뜻보기에 이것은 간단한 질문처럼 보이지만 해결하기가 상당히 까다 롭습니다. 그러나 문제를 해결하는 데 필요한 모든 요소가 이미 있으며 알고리즘을 약간만 조정하면됩니다.
요점은 다음과 같습니다.
필요한 것은 임계 이미지 (bw_copy)의 반전 된 이미지 (wb_copy)입니다.
당신은 마스크를 만드는 훌륭한 일을했습니다.
위의 마스크를 사용하여 bw_copy 및 wb_copy 모두에서 bitwise_and 연산을 실행합니다. 아래와 같은 결과를 얻을 수 있습니다.
보시다시피 귀하의 대답은 두 이미지 모두에서 벗어납니다. 모든 글꼴 blob에 대해 두 이미지에서 0이 아닌 픽셀을 계산하고 더 높은 수의 픽셀을 선택하기 만하면됩니다. 그렇게하면 원하는 결과를 얻을 수 있습니다.
코드를 수정 한 내용은 다음과 같습니다.
# finding contours
_,contours,_ = cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
mask = np.zeros(closed.shape, dtype=np.uint8)
mask1 = np.zeros(bw_copy.shape, dtype=np.uint8)
wb_copy = cv2.bitwise_not(bw_copy)
new_bw = np.zeros(bw_copy.shape, dtype=np.uint8)
for idx in range(len(contours)):
x, y, w, h = cv2.boundingRect(contours[idx])
mask[y:y + h, x:x + w] = 0
area = cv2.contourArea(contours[idx])
aspect_ratio = float(w) / h
cv2.drawContours(mask, contours, idx, (255, 255, 255), -1)
r = float(cv2.countNonZero(mask[y:y + h, x:x + w])) / (w * h)
# identify region of interest
if r > 0.34 and 0.52 < aspect_ratio < 13 and area > 145.0:
cv2.drawContours(mask1, [contours[idx]], -1, (255, 255, 255), -1)
bw_temp = cv2.bitwise_and(mask1[y:y + h, x:x + w],bw_copy[y:y + h, x:x + w])
wb_temp = cv2.bitwise_and(mask1[y:y + h, x:x + w],wb_copy[y:y + h, x:x + w])
bw_count = cv2.countNonZero(bw_temp)
wb_count = cv2.countNonZero(wb_temp)
if bw_count > wb_count:
new_bw[y:y + h, x:x + w]=np.copy(bw_copy[y:y + h, x:x + w])
else:
new_bw[y:y + h, x:x + w]=np.copy(wb_copy[y:y + h, x:x + w])
cv2.imshow('new_bw', new_bw)
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다