- vừa được xem lúc

Remove Watermark, Seal in images with OpenCv

0 0 24

Người đăng: To Duc Thang

Theo Viblo Asia

Trong bài toán về OCR có rất nhiều bài toán con đằng sau liên quan đến nội dung, chất lượng hình ảnh để đưa vào detec box và recognition cái box đó. Cụ thể như ta gặp phải là watermark, seal công ty nó sẽ làm nhiễu, ảnh hưởng đến nội dung, chất lượng OCR.Tuy nhiên cũng tùy vào mục đích sử dụng của mọi người, phù hợp với bài toán đặt ra nữa. Dưới đây thì mình sẽ sử dụng OpenCv để xử lý vấn đề watermark, seal này, cụ thể là remove seal công ty, watermark được đóng vào tài liệu, hóa đơn,.....

Case 1

Ta cùng phân tích đặc điểm của bài toán.

Như ta thấy trong hình trên đây có đặc điểm là con dấu và nội dung chữ là hai màu hoàn toàn khác nhau, cụ thể chữ màu đen và con dấu có màu đỏ. Khi ta quan sát bình thường bằng mắt thì như thế nhưng thực thế không hoàn toàn đúng như thế. Như mọi người đã biết một hình ảnh bình thường được tạo nên từ 3 màu RGB( Red, Green, Blue). Mỗi một pixel sẽ bao gồm 3 màu đó. Ví dụ như pixel có giá trị (0, 0, 0) sẽ là màu đen tuyệt đối, (255, 255, 255) sẽ là màu trắng tinh khôi, phải chăng là ta sẽ tìm giá trị pixel màu đỏ rồi xóa đi ?????

Ý tưởng ban đầu là ta sẽ dùng OpenCv để replace các giá trị pixel màu đỏ sang màu trắng (easy ???) ta cùng thử xem kết quả như thế nào.

def is_gray(a, b, c): r = 60 if a + b + c < 250: return True if abs(a - b) > r: return False if abs(a - c) > r: return False if abs(b - c) > r: return False return True def remove_watermark(image): image = image.convert("RGB") color_data = image.getdata() new_color = [] for item in color_data: if is_gray(item[0], item[1], item[2]): new_color.append(item) else: new_color.append((255, 255, 255)) image.putdata(new_color)
// img = np.array(image)
// cv2.imwrite("data_test/result/result.png",img[:, :, ::-1]) return image

Nếu ta dùng cách như trên mà replace không theo range, check từng giá trị trong một pixel thì mặc dù các đã xóa được dấu nhưng có một vấn đề là các chữ khác nó cũng bị mất nét chữ.?. Nguyên nhân là do mặc dù ta nhìn thấy chỉ có hai màu đỏ và đen nhưng thực tế khi ta zoom hình ảnh với opencv thì ta có thể thấy. Bởi vì các giá trị pixel là tổ hợp của ba màu rgb, nếu xét theo range giá trị như trên thì những giá trị pixel "hơi đen" nó cũng bị ảnh hưởng.

Case 2

Ta sẽ lấy một ví dụ như hình dưới đây :

Nhìn qua ta thấy rằng các hình ảnh trên mạng đều sử dụng kểu watermark như thế này. Cách đơn giản nhất là dùng clip trong numpy để xử lý vấn đề này.

img = cv2.imread(path_image) alpha = 2.596594846224838
beta = -161 new_img = alpha * img + beta
new_img = np.clip(new_img, 0, 255).astype(np.uint8)
cv2.imwrite("remove.png", new_img)

Và dưới đây là kết quả :

Nhìn qua có thể thấy là mặc dù đã remove được watermark, nhưng những chữ xung quanh cũng có sự thay đổi. Ta cũng thử một vài ảnh khác với cùng cách như trên

Bonus

Đặc biệt là các file định dạng pdf thì cũng thường có watermark như trên, cũng may là python cũng đã có lib convert pdf --> image :

from pdf2image import convert_from_path image = convert_from_path(pdf_path) def processing_image(image): // Remove 

Case 3

Cách tiếp theo là ta sử dụng là : tăng độ sáng cảu ảnh --> Xét Range --> Sử dụng cv2.dilate --> Contours --> Remove .

image = Image.fromarray(image)
image_contrast = ImageEnhance.Contrast(image).enhance(1.5) img_hsv = cv2.cvtColor(np.array(image_contrast)[:, :, ::-1], cv2.COLOR_BGR2HSV) red_lower = np.array([110, 50, 50], np.uint8)
red_upper = np.array([200, 255, 255], np.uint8)
red_mask = cv2.inRange(img_hsv, red_lower, red_upper) kernal = np.ones((5, 5), "uint8")
red_mask = cv2.dilate(red_mask, kernal) contours, _ = cv2.findContours(red_mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours: area = cv2.contourArea(contour) if(area > 50): x, y, w, h = cv2.boundingRect(contour) // cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2) # Draw Box cv2.rectangle(img, (x, y), (x + w, y + h), (255, 255, 255), -1) # Repalce

Về ý tưởng trong cách này là dùng thêm dilate ( nó thuộc phương pháp biến đổi hình thái học ) ngoài ra còn có Erosion. Mọi người có thể xem thêm để hiểu cách nó hoạt động. Ban đầu thì ta vẫn sử dụng range để lấy được cái Mask của con dấu màu đỏ , sau đó dùng kernal, dilatiion để tăng thêm các vùng xung quanh.

Case 4

Nếu dùng cách contour như bên trên, nếu trường hợp con dấu đè vào chữ thì kết quả là sẽ remove luôn chữ --> như thế không được. Tìm thử trong OpenCv thì có fun cv2.inpaint ( hàm này rất hữu ích )

image = Image.fromarray(image)
image_contrast = ImageEnhance.Contrast(image).enhance(1.5) img_hsv = cv2.cvtColor(np.array(image_contrast)[:, :, ::-1], cv2.COLOR_BGR2HSV) red_lower = np.array([110, 50, 50], np.uint8)
red_upper = np.array([200, 255, 255], np.uint8)
red_mask = cv2.inRange(img_hsv, red_lower, red_upper) kernal = np.ones((5, 5), "uint8")
red_mask = cv2.dilate(red_mask, kernal) dst = cv2.inpaint(img, red_mask, 0 , cv2.INPAINT_TELEA) return dst 

Kết quả

Ngoài ra khi dùng inpaint ta cũng có thể xóa bỏ, khôi phục ảnh bị cũ, hỏng. Có hai method được khai báo trong inpaint là cv2.INPAINT_TELEAcv2.INPAINT_NS. Thứ ta cần ở đây là image cần chỉnh sửa, quan trọng nhất là Mask image, vị trí mà ta cần chỉnh sửa. Như một số ví dụ dưới đây :

Quan sát hình trên ta thấy là ảnh input bị nhàu nát, bị mất một đoạn nhỏ, ta có thể khôi phục lại một chút khi dùng inpaint.

Tùy thuộc vào bài toán mà ta chọn cách giải quyết phù hợp với yêu cầu, các bạn có cách nào khác hay thì hãy chia sẻ với mình và mọi người để sau gặp phải thì ta có cách xử lý, tiết kiệm thời gian hơn.

Tham khảo

  1. https://viblo.asia/p/xu-ly-anh-erosion-dilation-opening-closing-4dbZNpWq5YM
  2. https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_photo/py_inpainting/py_inpainting.html

Bình luận

Bài viết tương tự

- vừa được xem lúc

Trích xuất thông tin bảng biểu cực đơn giản với OpenCV

Trong thời điểm nhà nước đang thúc đẩy mạnh mẽ quá trình chuyển đổi số như hiện nay, Document Understanding nói chung cũng như Table Extraction nói riêng đang trở thành một trong những lĩnh vực được quan tâm phát triển và chú trọng hàng đầu. Vậy Table Extraction là gì? Document Understanding là cái

0 0 213

- vừa được xem lúc

Tăng tốc độ đọc frame từ video với cv2.VideoCapture và OpenCV

Phân tích. Trong các hệ thống nhận diện ta thường gặp phải vấn đề thời gian detection của hệ thống khá là chậm.

0 0 103

- vừa được xem lúc

Xử lí ảnh: thuật toán cân bằng histogram ảnh

Lý thuyết. 1.

0 0 1k

- vừa được xem lúc

Hướng dẫn lưu video từ luồng camera sử dụng tkinter và opencv

Ở bài viết này thì mình sẽ hướng dẫn các bạn thiết kế 1 chương trình đơn giản để có thể show luồng camera từ máy tính hoặc luồng rtsp, sau đó có thể lưu video theo bao nhiêu giây đó tùy các bạn. Ở bài

0 0 38

- vừa được xem lúc

Haar Cascade là gì? Luận về một kỹ thuật chuyên dùng để nhận biết các khuôn mặt trong ảnh.

Mở bài. Sau khi mình đọc bài này của bạn Sơn team mình về đánh giá điểm khuôn mặt, đến đoạn bắt xem vùng nào chứa khuôn mặt trên ảnh, thì mình chợt nhận ra là mình không biết gì về cái này cả Sau khi

0 0 210

- vừa được xem lúc

Phân loại hình ảnh với Vision Transformer

Ví dụ này triển khai mô hình Vision Transformer (ViT) của Alexey Dosovitskiy để phân loại hình ảnh và thể hiện mô hình đó trên tập dữ liệu CIFAR-100. Mô hình ViT áp dụng kiến trúc Transformer với khả

0 0 16