python opencv去圖片水印

【背景】

  最近有一個需要爲圖片去水印的需求,於是各種折騰開始。

【背景瞭解圖片標準】

圖片使用RGB編碼,RGB色彩模式是工業界的一種顏色標準,是通過對紅(R)、綠(G)、藍(B)三個顏色通道的變化以及它們相互之間的疊加來得到各式各樣的顏色,RGB即是代表紅、綠、藍三個通道的顏色。

【分析圖片】

分析了圖片之後,發現規律:

1、圖片需要的圖形是黑色的

2、水印都是一種顏色:水紅

白色對應#FFFFFF就是 255 255 255

黑色對應#000000 就是 0     0     0

我們用rgb取色工具

發現紅色的字rgb有以下情況:差不多grb的相加和都在200以上,那麼我們寫程序的判斷基準就產生了:就是找到每個像素,如果像素和大於250,並且小於765(不是白色),就將這個像素點重置爲白色:255,255,255。

wKiom1SPtobjuVmnAACynVQSCD0887.jpg

wKioL1SPtyaQF27IAACmD0uzxKA365.jpg

wKiom1SPtofTtOB7AACrw0ual4Q368.jpg

wKioL1SPtyazDRqAAACscgzUL8Q380.jpg

得到以上邏輯之後,怎樣在代碼中實現?找了幾個python下處理圖像的庫,最終選擇了opencv。於是乎接着就要研究opencv的api了。

具體可以看看opencv的官網:http://opencv.org/

當然一開始你覺得看直接去看手冊很苦逼,也可以看看別人的程序找點感覺了。

【安裝opencv】

其實安裝opencv也是很折騰人的一個事情,mac下安裝opencv安裝可參考:

sudo brew tap homebrew/science
sudo brew install OpenCV


wKioL1SPt0Kz7vQvAAVKUiIbzNI551.jpg

注意安裝好了之後,需要將庫的地址做說明,具體看上圖紅框的位置。

有可能還需要

sudo  brew update


【具體代碼】

__author__ = 'River'
# -*- coding: utf-8 -*-
import cv2,os,shutil,datetime,re,time
from threading import Thread
from hashlib import md5
PICHASH= {}
def md5_file(name):
    try:
        m = md5()
        a_file = open(name, 'rb')
        m.update(a_file.read())
        a_file.close()
        return m.hexdigest()
    except:
        return None
def nowater(dir,newdir,dirlist):
    global  PICHASH
    for ppicdir in dirlist:
        if(os.path.isdir(dir+ppicdir)):
            sortfiles=os.listdir(dir+ppicdir)
            if '.DS_Store' in sortfiles:
                sortfiles.remove('.DS_Store')
            sortfiles.sort()
            for oldfile in sortfiles:
                filetype="."+oldfile.split(".")[len(oldfile.split("."))-1]
                picname_front=oldfile.split(filetype)[0]
                oldfile=dir+ppicdir+"/"+oldfile
                jpgname=picname_front+".jpg"
                jpgname=newdir+ppicdir+"/"+jpgname
                try:
                    oldfile_hash=md5_file(oldfile)
                    oldfile_tmphashvalue=PICHASH.get(oldfile_hash)
                    file_object = open('pichash.txt', 'a')
                    file_object.write(oldfile+":"+oldfile_hash+'\n')
                    file_object.close()
                    if(oldfile_tmphashvalue==None):#新文件,已經處理過的圖片,就不會再次處理了
                        if not os.path.exists(newdir+ppicdir):
                            os.makedirs(newdir+ppicdir)
                        #print oldfile  哈哈
                        #print jpgname
                        print datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")+","+oldfile+",ing\n"
                        img=cv2.imread(oldfile)
                        x,y,z=img.shape
                        if x < 10:#太小文件不處理
                            print datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")+","+jpgname+"文件太小,跳過"
                        elif x >8000:#太大的文件不處理
                            print datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")+","+jpgname+"文件太大,跳過"
                        elif not os.path.exists(jpgname):#這就是最關鍵的代碼了
                            for i in xrange(x):
                                for j in xrange(y):
                                    varP=img[i,j]
                                    if sum(varP)>250 and sum(varP)<765 :#大於250,小於765(sum比白色的小)
                                        img[i,j]=[255,255,255]
                            #cv2.imwrite(jpgname,img,[int(cv2.IMWRITE_JPEG_QUALITY),70])#linux跑悲劇了
                            cv2.imwrite(jpgname,img)
                            print "jpgname:"+jpgname
                            PICHASH[oldfile_hash]=oldfile
                            print datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")+","+oldfile+",done\n"
                        else:
                            print datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")+","+jpgname+"文件已存在,跳過\n"
                    elif(oldfile_tmphashvalue!=None):
                        if(os.path.exists(jpgname)):
                            print datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")+","+jpgname+"文件已存在,跳過\n"
                        else:
                            shutil.copyfile(oldfile_tmphashvalue,oldfile)
                            shutil.copyfile(oldfile,jpgname)
                            print datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")+","+jpgname+"和老文件一樣,拷貝舊文件,跳過"
                except Exception,e:
                    print "Exception:",e
                    continue
if __name__=='__main__':
    dir="pic/"
    newdir="picnew/"
    list0=[]
    list1=[]
    list2=[]
    list3=[]
    list4=[]
    for ppicdir in os.listdir(dir) :#生成多個list,主要是爲了併發處理多個目錄的圖片
        if(os.path.isdir(dir+ppicdir)):
                if (re.compile(r'^[0-1].*').match(str(ppicdir))):
                    list0.append(ppicdir)
                elif(re.compile(r'^[2-3].*').match(str(ppicdir))):
                    list1.append(ppicdir)
                elif(re.compile(r'^[4-5].*').match(str(ppicdir))):
                    list2.append(ppicdir)
                elif(re.compile(r'^[6-7].*').match(str(ppicdir))):
                    list3.append(ppicdir)
                elif(re.compile(r'^[8-9].*').match(str(ppicdir))):
                    list4.append(ppicdir)
                else:
                    continue
    #啓n線程並行處理
    Thread(target=nowater,args=(dir,newdir,list0)).start()#這裏只有
    Thread(target=nowater,args=(dir,newdir,list1,)).start()
    Thread(target=nowater,args=(dir,newdir,list2,)).start()
    Thread(target=nowater,args=(dir,newdir,list3,)).start()
    Thread(target=nowater,args=(dir,newdir,list4,)).start()

【最終效果】

wKioL1SPt4CiPm1xAAERfLsyXAQ911.jpg

wKiom1SPtuGSTVNCAACK7N9i7rI815.jpg

去除水印之後的效果:

wKiom1SPtvOg0clDAABx0GWPcY4695.jpg


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章