#-*- coding: UTF-8 -*-
import cv2
import numpy as np
from matplotlib import pyplot as plt
from PIL import Image,ImageDraw
import numpy as np
def first():
"""
根据图片确定A4之的边缘,并裁切出A4纸部分
"""
np.set_printoptions(threshold=np.inf)
img=cv2.imread('test.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
print (len(contours))
for i in range(0,len(contours)):
x, y, w, h = cv2.boundingRect(contours[i])
#cv2.rectangle(img, (x,y), (x+w,y+h), (153,153,0), 5)
#cv2.imshow("img", img)
#cv2.waitKey(0)
#cv2.destroyWindow("img")
newimage=img[y+5:y+h-5,x+40:x+w-30]
cv2.imwrite( "output.jpg",newimage)
def shuiping(image_data):
"""首先传递参数,读取的灰度图片;
随后,将图片二值化;接着进行水平投影;
利用水平投影的最后位置,确认出切割图片的坐标。
"""
image=image_data
limit = 130
table = []
#二值化,阈值200以下全部变为为0,其余变为255
for i in range(256):
if i < limit:
table.append(0)
else:
table.append(1)
image= image.point(table, '1')
#image.show()
image= np.array(image)
(h,w)=image.shape
a = [0 for z in range(0, h)]
#水平投影,数组里的数字对应水平位置黑色区域像素点长度
num =0
for j in range(0,h):
for i in range(0,w):
if image[j,i]==0:
num+=1
a[j]+=1
image[j,i]=255
for j in range(0,h):
for i in range(0,a[j]):
image[j,i]=0
image=Image.fromarray(image)
image.show()
#水平投影最后会有结束点,结束点最后一个位置是黑色的,
#对应数组不为0,白色位置对应数组位置全部为0
x1=0
y1=0
y2=0
x2=image.width
list_pic=[]
for i in range(len(a)):
if a[i-1]==0 or a[i]!=0:
y2+=1
elif a[i-1]!=0 and a[i]==0:
y2+=1
list_pic.append([x1,y1,x2,y1+y2])
y1=y1+y2
y2=0
num=1
pic_data=[]
for i in list_pic:
croping = image_data.crop(i)
croping.save( "shuiping/"+str(num) + '.jpg')
num+=1
pic_data.append(croping)
print("分割完成,已保存!")
return pic_data
def chuizhi(image_data):
"""首先传递参数,读取的灰度图片;
随后,将图片二值化;接着进行垂直投影;
利用垂直投影的间断特点,确认出切割图片的坐标。
"""
num=1
count=1
for pic in image_data:
image=pic
limit = 200
table = []
#二值化,阈值200以下全部变为为0,其余变为255
for i in range(256):
if i < limit:
table.append(0)
else:
table.append(1)
image= image.point(table, '1')
image= np.array(image)
(h,w)=image.shape
print (h,w)
#垂直投影,数组里的数字对应垂直位置黑色区域像素点长度
b = [0 for z in range(0, w)]
for i in range(0,w):
for j in range(0,h):
if image[j,i]==0:
b[i]+=1
image[j,i]=255
for i in range(0,w):
for j in range(0,b[i]):
image[j,i]=0
image=Image.fromarray(image)
#image.show()
x1=0
x2=0
y1=h
y2=0
list=[]
#垂直投影最后会有结束点,结束点最后一个位置是黑色的,
#对应数组不为0,白色位置对应数组位置全部为0
for i in range(len(b)):
if b[i-1]==0 or b[i]!=0:
y2+=1
elif b[i-1]!=0 and b[i]==0:
y2+=1
list.append([x1,x2,(x1+y2),y1-1])
x1=x1+y2
y2=0
for i in list:
croping = pic.crop(i)
croping.save( "chuizhi/"+str(num) + '.jpg')
num+=1
for i in list:
draw=ImageDraw.Draw(pic)
draw.rectangle(i)
#pic.show()
pic.save("rec"+ str(count)+".jpg")
count+=1
print("分割完成,已保存!")
def main():
#first()
img_path="test1.jpg"
image_data=(Image.open(img_path).convert('L'))
#image_data.show()
pic=shuiping(image_data)
chuizhi(pic)
main()
测试图片
输出结果:
说明:此图片是PS输出的照片,效果很好。手机拍摄的图片含有很多噪声,因此效果不好。