收到的需求是在一個圖上匹配到水印 而後將原來的水印換成一個新水印python
先要安裝一個庫 庫文件代碼以下:算法
# coding=utf-8 import cv2 import numpy as np # 膨脹算法 Kernel _DILATE_KERNEL = np.array([[0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [1, 1, 1, 1, 1], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0]], dtype=np.uint8) class WatermarkRemover(object): """" 去除圖片中的水印(Remove Watermark) """ def __init__(self, verbose=True): self.verbose = verbose self.watermark_template_gray_img = None self.watermark_template_mask_img = None self.watermark_template_h = 0 self.watermark_template_w = 0 self.watermark_start_x = 0 self.watermark_start_y = 0 def load_watermark_template(self, watermark_template_filename): """ 加載水印模板,以便後面批量處理去除水印 :param watermark_template_filename: :return: """ self.generate_template_gray_and_mask(watermark_template_filename) def dilate(self, img): """ 對圖片進行膨脹計算 :param img: :return: """ dilated = cv2.dilate(img, _DILATE_KERNEL) return dilated def generate_template_gray_and_mask(self, watermark_template_filename): """ 處理水印模板,生成對應的檢索位圖和掩碼位圖 檢索位圖 即處理後的灰度圖,去除了非文字部分 :param watermark_template_filename: 水印模板圖片文件名稱 :return: x1, y1, x2, y2 """ # 水印模板原圖 img = cv2.imread(watermark_template_filename) # 灰度圖、掩碼圖 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) _, mask = cv2.threshold(gray, 0, 255, cv2.THRESH_TOZERO + cv2.THRESH_OTSU) _, mask = cv2.threshold(mask, 127, 255, cv2.THRESH_BINARY) mask = self.dilate(mask) # 使得掩碼膨脹一圈,以避免留下邊緣沒有被修復 #mask = self.dilate(mask) # 使得掩碼膨脹一圈,以避免留下邊緣沒有被修復 # 水印模板原圖去除非文字部分 img = cv2.bitwise_and(img, img, mask=mask) # 後面修圖時須要用到三個通道 mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR) self.watermark_template_gray_img = gray self.watermark_template_mask_img = mask self.watermark_template_h = img.shape[0] self.watermark_template_w = img.shape[1] # cv2.imwrite('watermark-template-gray.jpg', gray) # cv2.imwrite('watermark-template-mask.jpg', mask) return gray, mask def find_watermark(self, filename): """ 從原圖中尋找水印位置 :param filename: :return: x1, y1, x2, y2 """ # Load the images in gray scale gray_img = cv2.imread(filename, 0) return self.find_watermark_from_gray(gray_img, self.watermark_template_gray_img) def find_watermark_from_gray(self, gray_img, watermark_template_gray_img): """ 從原圖的灰度圖中尋找水印位置 :param gray_img: 原圖的灰度圖 :param watermark_template_gray_img: 水印模板的灰度圖 :return: x1, y1, x2, y2 """ # Load the images in gray scale method = cv2.TM_CCOEFF # Apply template Matching res = cv2.matchTemplate(gray_img, watermark_template_gray_img, method) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) # If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]: x, y = min_loc else: x, y = max_loc return x, y, x + self.watermark_template_w, y + self.watermark_template_h def remove_watermark_raw(self, img, watermark_template_gray_img, watermark_template_mask_img): """ 去除圖片中的水印 :param img: 待去除水印圖片位圖 :param watermark_template_gray_img: 水印模板的灰度圖片位圖,用於肯定水印位置 :param watermark_template_mask_img: 水印模板的掩碼圖片位圖,用於修復原始圖片 :return: 去除水印後的圖片位圖 """ # 尋找水印位置 img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) x1, y1, x2, y2 = self.find_watermark_from_gray(img_gray, watermark_template_gray_img) self.watermark_start_x = x1 self.watermark_start_y = y1 # 製做原圖的水印位置遮板 mask = np.zeros(img.shape, np.uint8) # watermark_template_mask_img = cv2.cvtColor(watermark_template_gray_img, cv2.COLOR_GRAY2BGR) # mask[y1:y1 + self.watermark_template_h, x1:x1 + self.watermark_template_w] = watermark_template_mask_img mask[y1:y2, x1:x2] = watermark_template_mask_img mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY) # 用遮板進行圖片修復,使用 TELEA 算法 dst = cv2.inpaint(img, mask, 4, cv2.INPAINT_TELEA) # cv2.imwrite('dst.jpg', dst) return dst def remove_watermark(self, filename, output_filename=None): """ 去除圖片中的水印 :param filename: 待去除水印圖片文件名稱 :param output_filename: 去除水印圖片後的輸出文件名稱 :return: 去除水印後的圖片位圖 """ # 讀取原圖 img = cv2.imread(filename) dst = self.remove_watermark_raw(img, self.watermark_template_gray_img, self.watermark_template_mask_img ) if output_filename is not None: cv2.imwrite(output_filename, dst) return dst
注意 上面的代碼要加上這兩句 才能顯示 原來水印的位置
去水印代碼以下:markdown
from nowatermark import WatermarkRemover path = 'E:/sample/' watermark_template_filename = path + 'watermark.png' remover = WatermarkRemover() remover.load_watermark_template(watermark_template_filename) remover.remove_watermark(path + '20180516144931.png', path + '20180516144932.png') print(remover.watermark_start_x) print(remover.watermark_start_y)
這裏輸出的兩個值 是指的水印在原圖中的位置 ide
加水印代碼以下:ui
import cv2 import numpy as np path = 'E:/sample/' matimage = cv2.imread(path + '20180516144932.png') #matimagenew = np.zeros((matimage.shape[0],matimage.shape[1],3)) matimagenew = matimage-matimage watermark_template_filename = path + 'watermark.png' matlogo = cv2.imread(watermark_template_filename) matimagenew[359:359+matlogo.shape[0],453:453+matlogo.shape[1]] = matlogo imagenew = cv2.addWeighted(matimage,1,matimagenew,1,1) savepath = path + '20180516144933.png' cv2.imwrite(savepath,imagenew)
其中的359爲水印在原圖中的位置的縱座標 453爲橫座標code