文件图片检测

功能:
1.查看图片分辨率
2.查看图片exif信息 来确定文件是否经修改
3.对比图片和模板图片 标记处不同之处

    > import sys import cv2 
    > import numpy as np from PIL 
    > import Image   

Open Source Computer Vision Library.OpenCV于1999年由Intel建立,如今由Willow Garage提供支持。OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows、MacOS操作系统上。它轻量级而且高效——由一系列 C 函数和少量C++类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。

NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。

PIL可以做很多和图像处理相关的事情:
图像归档(Image Archives)。PIL非常适合于图像归档以及图像的批处理任务。你可以使用PIL创建缩略图,转换图像格式,打印图像等等。
图像展示(Image Display)。PIL较新的版本支持包括Tk PhotoImage,BitmapImage还有Windows DIB等接口。PIL支持众多的GUI框架接口,可以用于图像展示。
图像处理(Image Processing)。PIL包括了基础的图像处理函数,包括对点的处理,使用众多的卷积核(convolution kernels)做过滤(filter),还有颜色空间的转换。PIL库同样支持图像的大小转换,图像旋转,以及任意的仿射变换。PIL还有一些直方图的方法,允许你展示图像的一些统计特性。这个可以用来实现图像的自动对比度增强,还有全局的统计分析等。

    > def preprocess(gray):
    >     # 1. Sobel算子,x方向求梯度
    >     sobel = cv2.Sobel(gray, cv2.CV_8U, 1, 0, ksize = 3)
    >     # 2. 二值化
    >     ret, binary = cv2.threshold(sobel, 0, 255, cv2.THRESH_OTSU+cv2.THRESH_BINARY)
    >  
    >     # 3. 膨胀和腐蚀操作的核函数
    >     element1 = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 9))
    >     element2 = cv2.getStructuringElement(cv2.MORPH_RECT, (24, 6))
    >  
    >     # 4. 膨胀一次,让轮廓突出
    >     dilation = cv2.dilate(binary, element2, iterations = 1)
    >  
    >     # 5. 腐蚀一次,去掉细节,如表格线等。注意这里去掉的是竖直的线
    >     erosion = cv2.erode(dilation, element1, iterations = 1)
    >  
    >     # 6. 再次膨胀,让轮廓明显一些
    >     dilation2 = cv2.dilate(erosion, element2, iterations = 3)
    >  
    >     # 7. 存储中间图片 
    >     #cv2.imwrite("binary.png", binary)
    >     #cv2.imwrite("dilation.png", dilation)
    >     #cv2.imwrite("erosion.png", erosion)
    >     #cv2.imwrite("dilation2.png", dilation2)
    >  
    >     return dilation2

索贝尔算子(Sobeloperator)主要用作边缘检测,在技术上,它是一离散性差分算子,用来运算图像亮度函数的灰度之近似值。在图像的任何一点使用此算子,将会产生对应的灰度矢量或是其法矢量。
Sobel算子依然是一种过滤器,只是其是带有方向的。
dst = cv2.Sobel(src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]])
前四个是必须的参数:

  • src参数是需要处理的图像;
  • ddepth参数是图像的深度,-1表示采用的是与原图像相同的深度。目标图像的深度必须大于等于原图像的深度;
  • dx和dy表示的是求导的阶数,0表示这个方向上没有求导,一般为0、1、2。

其后是可选的参数:

  • ksize是Sobel算子的大小,必须为1、3、5、7。
  • scale是缩放导数的比例常数,默认情况下没有伸缩系数;
  • delta是一个可选的增量,将会加到最终的dst中,同样,默认情况下没有额外的值加到dst中;
  • borderType是判断图像边界的模式。这个参数默认值为cv2.BORDER_DEFAULT。

图像二值化( Image Binarization)就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果的过程。在数字图像处理中,二值图像占有非常重要的地位,图像的二值化使图像中数据量大为减少,从而能凸显出目标的轮廓。

threshold:固定阈值二值化
ret, dst = cv2.threshold(src, thresh, maxval, type)
src: 输入图,只能输入单通道图像,通常来说为灰度图
dst: 输出图
thresh: 阈值
maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值
type:二值化操作的类型,包含以下5种类型: cv2.THRESH_BINARY; cv2.THRESH_BINARY_INV; cv2.THRESH_TRUNC; cv2.THRESH_TOZERO;cv2.THRESH_TOZERO_INV

形态学操作其实就是改变物体的形状,比如腐蚀就是"变瘦",膨胀就是"变胖"。形态学操作一般作用于二值化图,来连接相邻的元素或分离成独立的元素。腐蚀和膨胀是针对图片中的白色部分。

形态学处理的核心就是定义结构元素,在OpenCV-Python中,可以使用其自带的getStructuringElement函数
二维结构元素可以理解成一个二维矩阵,矩阵元素的值为0或者1;通常结构元素要小于待处理的图像。
getStructuringElement函数会返回指定形状和尺寸的结构元素。

    >     def findTextRegion(img):
    >     region = []
    >  
    >     # 1. 查找轮廓
    >     contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    >  
    >     # 2. 筛选那些面积小的
    >     for i in range(len(contours)):
    >         cnt = contours[i]
    >         # 计算该轮廓的面积
    >         area = cv2.contourArea(cnt) 
    >  
    >         # 面积小的都筛选掉
    >         if(area < 1000):
    >             continue
    >  
    >         # 轮廓近似,作用很小
    >         epsilon = 0.001 * cv2.arcLength(cnt, True)
    >         approx = cv2.approxPolyDP(cnt, epsilon, True)
    >  
    >         # 找到最小的矩形,该矩形可能有方向
    >         rect = cv2.minAreaRect(cnt)
    >         #print ("rect is: ")
    >         #print (rect)
    >  
    >         # box是四个点的坐标
    >         box = cv2.boxPoints(rect)
    >         box = np.int0(box)
    >  
    >         # 计算高和宽
    >         height = abs(box[0][1] - box[2][1])
    >         width = abs(box[0][0] - box[2][0])
    >  
    >         # 筛选那些太细的矩形,留下扁的
    >         if(height > width * 1.2):
    >             continue
    >  
    >         region.append(box)
    >  
    >     return region
    >     def detect(img,module):
    >     # 1.  转化成灰度图
    >     gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    >     gray1 = cv2.cvtColor(module, cv2.COLOR_BGR2GRAY)
    >     # 2. 形态学变换的预处理,得到可以查找矩形的图片
    >     dilation = preprocess(gray)
    >     dilation1 = preprocess(gray1)
    >     # 3. 查找和筛选文字区域
    >     region = findTextRegion(dilation)
    >     region1 = findTextRegion(dilation1)
    >     #删除重复部分
    >     more=delete(region1,region)
    >     less=delete(region,region1)
    >     # 4. 用绿线画出这些找到的轮廓
    >     for box in more:
    >         cv2.drawContours(img, [box], 0, (0,0,200), 2)
    >     for box in less:
    >         cv2.drawContours(img, [box], 0, (0,200,0), 2)   
    >     cv2.namedWindow("img", cv2.WINDOW_NORMAL)
    >     cv2.imshow("img", img)
    >     print("有",len(less)+len(more),"处文字位置与模板不符")
    >     # 带轮廓的图片
    >     #cv2.imwrite("contours.png", img)
    >     cv2.waitKey(0)
    >     cv2.destroyAllWindows() def compare(list1,list2):
    >     d=0
    >     for i in range(len(list1)):
    >         if abs(list1[i][1]-list2[i][1])+abs(list1[i][0]-list2[i][0])>117:
    >             d=d+1
    >     return d
    >      def delete(region1,region):
    >     l=list(region)
    >     l1=list(region1)
    >     for i in l1:
    >         for j in range(len(l)):
    >             if compare(i,l[j-1])==0:
    >                 del(l[j-1])
    >     return l   if __name__ == '__main__':
    >     # 读取文件
    >     modulePath='2.jpg'
    >     imagePath = '1.jpg'
    >     module = cv2.imread(modulePath)
    >     img = cv2.imread(imagePath)
    >     #1.查看文件分辨率
    >     im=Image.open(imagePath)
    >     print('分辨率:',im.info['dpi'])
    >     #2.查看文件exif信息
    >     if hasattr(im,'_getexif')or hasattr(img,'adobe'):
    >         print('文件经过修改,信息如下:',im.info)
    >     else:
    >         print("文件没有修改痕迹")
    >     #3.判断文字位置是否与模板相符
    >     detect(img,module)


参考资料:
https://www.jianshu.com/p/eacaa97cb2f7
https://blog.csdn.net/sinat_21258931/article/details/61418681

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值