为了账号安全,请及时绑定邮箱和手机立即绑定

python opencv去图片水印

标签:
Python


【背景】

  最近有一个需要为图片去水印的需求,于是各种折腾开始。

【背景了解图片标准】

图片使用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

©著作权归作者所有:来自51CTO博客作者hh2o的原创作品,如需转载,请与作者联系,否则将追究法律责任


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消