導讀
本文主要介紹一個去除紙張中顔色筆迹/墨迹的執行個體,并将Halcon實作轉為OpenCV。
執行個體來源
執行個體來源于51Halcon論壇的讨論貼:
https://www.51halcon.com/forum.php?mod=viewthread&tid=4766
Halcon實作
參考回帖内容,将代碼整理如下:
read_image (Image, './test.jpg')
get_image_size (Image, Width, Height)
decompose3 (Image, ImageR, ImageG, ImageB)
trans_from_rgb (ImageR, ImageG, ImageB, ImageY, ImageI, ImageQ, 'yiq')
threshold (ImageQ, Regions, 132, 255)
dilation_rectangle1 (Regions, RegionDilation, 25, 15)
inpainting_texture (Image, RegionDilation, InpaintedImage, 5, 20, 0, 'none', 0)
如上圖所示,可以較好的去除圖中紅色和藍色的筆迹。
OpenCV實作
分析實作方法與思路:
[1] 将原圖從BGR顔色空間轉為YIQ顔色空間;
[2] 分離Q通道圖像對其做二值化處理;
[3] 矩形核做膨脹操作,将筆迹區域連接配接
[4] 将膨脹後的圖像作為mask,傳給inpaint函數,通過圖像修複來去除筆迹。
實作代碼(Python-OpenCV):
#公衆号:OpenCV與Halcon視覺
import cv2
import numpy as np
img = cv2.imread('test.jpg')
cv2.imshow('src',img)
img_q = np.zeros((img.shape[0],img.shape[1],1),np.float32)
for i in range(0,img.shape[0]):
for j in range(0,img.shape[1]):
B = img[i,j,0]
G = img[i,j,1]
R = img[i,j,2]
img_q[i,j] = 0.214*R - 0.522*G + 0.309*B
cv2.normalize(img_q, img_q, 0, 255, cv2.NORM_MINMAX, -1)
imgQ = cv2.convertScaleAbs(img_q)
cv2.imshow('imgQ',imgQ)
ret, thresImg= cv2.threshold(imgQ, 165, 255, cv2.THRESH_BINARY)
cv2.imshow('thresh',thresImg)
k1=np.ones((20,30), np.uint8)#指定膨脹核大小
thresImg = cv2.dilate(thresImg, k1, iteratinotallow=1)
cv2.imshow('dilation', thresImg)
result = cv2.inpaint(img,thresImg,3,cv2.INPAINT_NS)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
逐漸效果示範
原圖:src
Q通道轉8位顯示:imgQ
二值化效果:thresImg
膨脹效果:dilation
inpaint修複效果:result
結尾語
[1] 提取筆迹的方法有很多種,本文使用的是YIQ顔色空間的Q通道圖像(直接對單個通道門檻值處理較簡單),大家也可以使用其他顔色空間提取紅色和藍色即可(可能需要使用inRange函數在三個通道處理);
[2] RGB顔色空間與YIQ顔色空間的轉換:
① 網上流行的轉換公式:
② Halcon算子幫助文檔中的轉換公式:
二者略有差異,本文使用的是Halcon幫助文檔中的轉換方法,直接計算得到Q通道圖像。