Daniel Reetz, the founder of the DIY Book Scanner community, has recently started making videos of prototyping and shop tips. If you are tinkering with a book scanner (or any other project) in your home shop, these tips will come in handy. https://www.youtube.com/channel/UCn0gq8 ... g_8K1nfInQ

Hello.I want to give a gift to you for 2018.Splitting the page

General discussion about software packages and releases, new software you've found, and threads by programmers and script writers.
Post Reply
qqmxdpo
Posts: 12
Joined: 24 Sep 2016, 02:13
Number of books owned: 0
Country: china

Hello.I want to give a gift to you for 2018.Splitting the page

Post by qqmxdpo » 31 Dec 2017, 23:29

I firstly to say sorry for my English cause I am a Chinese.And I want to say I code something(python and opencv) to deal with the pictures from my two mobile phone(800W and 1200W).Its worked. That is my pictures and I will show my codes after days. And my e-mail is qqmxdpo@126.com


Image

Image

Image

Image

Image

Image

Code: Select all

#!/usr/bin/env python
#-8- coding: utf-8 -*-

#测试摄像头为800w 1200w

import numpy as np
import cv2
import os

def dingwei(img1,img,img_origin,a):#第一个参数时候要处理的图片,第二个参数为文件名,第三个参数为原图片
    
    img_fc, contours, hierarchy = cv2.findContours(img1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)#分析轮廓检测函数
    #cv2.imwrite('out/debug.jpg',img_fc)#debug函数

    hierarchy = hierarchy[0]
    found = []
    area=[]
    
    for i in range(len(contours)):#检测标记图形
        k = i
        c = 0
        while hierarchy[k][2] != -1:
            k = hierarchy[k][2]
            c = c + 1
        if c == 5:# 3 5
            found.append(i)
            area.append(cv2.contourArea(contours[i]))#筛选出满足条件的标记(有些图片二值化之后变成标记)
    found_need=[]
    found_need.append(found[area.index(max(area))])
    #print (found_need)
   
    boxes = []
    for i in found_need:
        #cv2.drawContours(img_origin, contours,i, (0, 255, 0), 10)#检测函数,画出轮廓的位置
        rect = cv2.minAreaRect(contours[i])#四个矩形是顺时针排序,最左下角为第一矩形
        box = cv2.boxPoints(rect)
        box = map(tuple, box)
        boxes.append(box)#四个顶点是顺时针排序,最左下角为第一个点
        a.append(list(boxes[0]))#用a列表储存每个检出出来的矩形的四个顶点
    #print (a)
        #(list(boxes[1]))[0]顶点的提取格式
    '''#调试函数
    #cv2.circle(img,contours,513,(0,255,0),5)检测函数,画圆看需要的点的位置
    #print(list(boxes[1])[0])'''
    #cv2.drawContours(img_origin, contours,i, (0, 255, 0), 10)
    #cv2.imwrite('out/img_origin.jpg',img_origin)#debug函数

def shibie(img,erzhi,fangxiang,h):
    img_origin = cv2.imread(img)
    #cv2.imwrite('a.jpg',img_origin)#debug函数
    
    img_gray =cv2.imread(img,0)
    #edges = cv2.Canny(img_gray, 50 ,100)#轮廓边缘函数检测#debug函数
    
    th2 = cv2.adaptiveThreshold(img_gray,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,41,13)#35才能看得多深浅不一的轮廓 10过滤一些模糊的轮廓

    img_gb = cv2.GaussianBlur(th2, (21,21), 0)#17 21..........
    #img_gb = cv2.blur(img1, (3,3))
    
    edges = cv2.Canny(img_gb, 50 ,100)#轮廓边缘函数检测............
    #cv2.imwrite('out/edges.jpg',edges)#debug函数
    kernel = np.ones((5,5),np.uint8) #3 5..........................
    #kernel1 = np.ones((3,3),np.uint8)
    img_gray = cv2.dilate(edges,kernel,iterations = 1)#膨胀,连通断开的线段
    #erosion = cv2.erode(dilation,kernel1,iterations = 1)#腐蚀,修复过于膨胀
    cv2.imwrite('out/edges.jpg',img_gray)#debug函数

    img1=img_gray.copy()#img1为识别的第一块坐标,右下角的点,为横坐标的1/3 纵坐标的1/6
    img1[0:int(img_gray.shape[0]*5/6),0:int(img_gray.shape[1])]=0
    img1[0:int(img_gray.shape[0]),0:int(img_gray.shape[1]*2/3)]=0
    
    img2=img_gray.copy()#img2为识别的第二块坐标,左下角的点
    img2[0:int(img_gray.shape[0]*5/6),0:int(img_gray.shape[1])]=0
    img2[int(img_gray.shape[0]*2/3):int(img_gray.shape[0]),int(img_gray.shape[1]/3):int(img_gray.shape[1])]=0

    img3=img_gray.copy()#img2为识别的第三块坐标,左上角的点
    img3[0:int(img_gray.shape[0]/6),int(img_gray.shape[1]/3):int(img_gray.shape[1])]=0
    img3[int(img_gray.shape[0]/6):int(img_gray.shape[0]),0:int(img_gray.shape[1])]=0

    img4=img_gray.copy()#img2为识别的第四块坐标,右上角的点
    img4[0:int(img_gray.shape[0]/6),0:int(img_gray.shape[1]*2/3)]=0
    img4[int(img_gray.shape[0]/6):int(img_gray.shape[0]),0:int(img_gray.shape[1])]=0
    #cv2.imwrite('out/test1.jpg',img1)#debug函数
    #cv2.imwrite('out/test2.jpg',img2)#debug函数
    #cv2.imwrite('out/test3.jpg',img3)#debug函数
    #cv2.imwrite('out/test4.jpg',img4)#debug函数
    
    a=[]#储存所有矩形的四个顶点
    
    try:
        dingwei(img1,img,img_origin,a)
        dingwei(img2,img,img_origin,a)
        dingwei(img3,img,img_origin,a)
        dingwei(img4,img,img_origin,a)

        for i in range(len(a)):#去除列表中的空列表
            for j in a:
                
                if [] ==j:
                    a.remove(j)
        #print(a)
        
        c=[]
        d=[]
        e=[]
        f=[]
        for i  in (0,1,2,3):
            c.append(a[0][i][1])
            d.append(a[1][i][1])
            e.append(a[2][i][1])
            f.append(a[3][i][1])
        
            
        x0,y0=a[0][c.index(min(c))]#仿射变换需要的四个点,左右页面选择的点不同,在这里变化 右 1100 左 2233
        x1,y1=a[1][d.index(min(d))]
        x2,y2=a[2][e.index(max(e))]
        x3,y3=a[3][f.index(max(f))]
        if fangxiang=='zuo':#判断是左页面
            x3,y3=(x3+200),((y3-y2)/(x3-x2)*(x3+200-x2)+y2)
            x0,y0=(x0+200),((y0-y1)/(x0-x1)*(x0+200-x1)+y1)
        else:
            if fangxiang=='you':#判断是右页面
                x1,y1=(x1-200),((y0-y1)/(x0-x1)*(x1-200-x0)+y0)
                x2,y2=(x2-200),((y2-y3)/(x2-x3)*(x2-200-x3)+y3)
            else:
                pass
        
        width,height=3120,4160#输出页面为3120 4160
        pts1 = np.float32([[x0,y0],[x1,y1],[x2,y2],[x3,y3]])
        pts2 = np.float32([[width,height],[0,height],[0,0],[width,0]]) 
        M=cv2.getPerspectiveTransform(pts1,pts2)
        #th3 = cv2.adaptiveThreshold(img_origin,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,3,3)#二值化 
        dst = cv2.warpPerspective(img_origin,M,(width,height))
        
        if int(erzhi) ==0:
            dst = cv2.cvtColor(dst,cv2.COLOR_BGR2GRAY)
            #dst = cv2.adaptiveThreshold(dst,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,3,3)
            ret,dst=cv2.threshold(dst,130,255,cv2.THRESH_BINARY)
        else:
            pass
        
        tempfilename=os.path.splitext(img)#文件名变更
        weizhi=str('out/'+tempfilename[0]+'_new.jpg')
        
        print(weizhi)
        cv2.imwrite(weizhi,dst)
    except:
        h.append(img)
    
def chuli(erzhi,fangxiang):
    i=0#统计处理的图片的数量
    if os.path.exists('out')==False:
        os.mkdir('out')
    else:
        pass
    
    print(r'''
以下为使用说明:
1)所有图片的文件名必须为 英文 或者 数字 .
尽管处理结果不影响原图片,但处理前必须手
工处理没有标记的或标记不全的图片,本程序没
有设置异常判断.(最好在ide运行)
标记放置为 正方形向逆时针偏移10度的形状(约菱形)

.........现在开始图片处理,输出文件路径为.........''')
    h=[]   
    for file in os.listdir("."):
        if file =='书籍图片处理(4比3版本).py' or file =='out':#过滤本脚本的名字
            continue
        else:
            shibie(file,erzhi,fangxiang,h)
            i=i+1
                        
    print('................共处理了 '+str(i)+' 张图片................')
    g=input('处理结束')

    
    print('\n以下文件处理失败:')
    #循环打印出哪些文件没有被处理
    for i in h:
        print(i)
    h=input('.................')

fangxiang=input('\n现在将该目录下的图片进行批量裁剪,仿射变换,原图输出,输入"zuo"或者"you",进行裁剪调整')
chuli(1,fangxiang)





Post Reply