• Python 图片处理笔记


    1. import numpy as np
    2. import cv2
    3. import os
    4. import matplotlib.pyplot as plt
    5. # 去除黑边框
    6. def remove_the_blackborder(image):
    7. image = cv2.imread(image) #读取图片
    8. img = cv2.medianBlur(image, 5) #中值滤波,去除黑色边际中可能含有的噪声干扰
    9. #medianBlur( InputArray src, OutputArray dst, int ksize );
    10. #这里的src代表输入图像,dst代表输出图像,ksize 必须是正数且为奇数
    11. #该函数使用中值滤波器来平滑图像,可以消除图像中的小点,该值越大,则消除的点越大
    12. b = cv2.threshold(img, 3, 255, cv2.THRESH_BINARY) #调整裁剪效果
    13. #大于3 的像素点都处理成第三个参数值,小于3的像素点都处理成0
    14. #大于3的像素点,都替换成纯白色(RGB==255)
    15. binary_image = b[1] #二值图--具有三通道
    16. #彩色图像: 有blue,green,red三个通道,取值范围均为0-255
    17. #灰度图:只有一个通道0-255,所以一共有256种颜色
    18. #二值图像:只有两种颜色,黑色和白色,二值化就是把图像的像素转变为0或者255,只有这两个像素值。0白色 1黑色 。0是黑色,255是白色
    19. binary_image = cv2.cvtColor(binary_image,cv2.COLOR_BGR2GRAY)
    20. #彩色图像,进行RGB到灰度的转换
    21. # print(binary_image.shape) #改为单通道
    22. edges_y, edges_x = np.where(binary_image==255) ##h, w
    23. #选取白色(RGB ==255)点的坐标
    24. #白色(RGB ==255)点的边界就是我们要保留的图片
    25. bottom = min(edges_y)
    26. top = max(edges_y)
    27. height = top - bottom
    28. left = min(edges_x)
    29. right = max(edges_x)
    30. height = top - bottom
    31. width = right - left
    32. #微调
    33. # 实际操作过程中发现,去掉边框的图像,仍然有几个像素数宽度的黑框,这里手动去掉
    34. boder = 3
    35. bottom = bottom + boder
    36. height = height - (boder * 2)
    37. left = left + boder
    38. width = width - (boder * 2)
    39. res_image = image[bottom:bottom+height, left:left+width]
    40. return res_image

    cv2.medianBlur

     img = cv2.medianBlur(image, 5) #中值滤波,去除黑色边际中可能含有的噪声干扰

    #medianBlur( InputArray src, OutputArray dst, int ksize );
    #这里的src代表输入图像,dst代表输出图像,ksize 必须是正数且为奇数
    #该函数使用中值滤波器来平滑图像,可以消除图像中的小点,该值越大,则消除的点越大

    cv2.threshold

    b = cv2.threshold(img, 3, 255, cv2.THRESH_BINARY) #调整裁剪效果

    #大于3 的像素点都处理成第三个参数值,小于3的像素点都处理成0

    #大于3的像素点,都替换成纯白色(RGB==255)

    https://zhuanlan.zhihu.com/p/511579219?utm_id=0


        binary_image = b[1]            #二值图--具有三通道

    cv2.cvtColor


        binary_image = cv2.cvtColor(binary_image,cv2.COLOR_BGR2GRAY)

    #彩色图像,进行RGB到灰度的转换    # print(binary_image.shape)     #改为单通道

    OtherS

    print(list(set(edges_y)))  对原列表去重并按从小到大排序

    np.argmax(np.bincount(edges_x)) 

    Counter(edges_x).most_common(20) 找出出现次数最多的几个元素

    分割清楚脏背景

    1. import cv2
    2. import numpy as np
    3. from skimage.filters import unsharp_mask
    4. from skimage.filters import gaussian
    5. from skimage.restoration import denoise_tv_chambolle
    6. import matplotlib.pyplot as plt
    7. from collections import Counter
    8. #分割图片,提取每一个 方格字 其他的部分,设置成白色RGB==255
    9. def clean_Zang_background_by_Fengge(image):
    10. image = cv2.imread(image) #读取图片
    11. img = cv2.medianBlur(image, 5) #中值滤波,去除黑色边际中可能含有的噪声干扰
    12. #medianBlur( InputArray src, OutputArray dst, int ksize );
    13. #这里的src代表输入图像,dst代表输出图像,ksize 必须是正数且为奇数
    14. #该函数使用中值滤波器来平滑图像,可以消除图像中的小点,该值越大,则消除的点越大
    15. b = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) #调整裁剪效果
    16. #大于190 的像素点都处理成 255 白色
    17. #计算
    18. binary_image = b[1] #二值图--具有三通道
    19. #彩色图像: 有blue,green,red三个通道,取值范围均为0-255
    20. #灰度图:只有一个通道0-255,所以一共有256种颜色
    21. #二值图像:只有两种颜色,黑色和白色,二值化就是把图像的像素转变为0或者255,只有这两个像素值。0白色 1黑色 。0是黑色,255是白色
    22. binary_image = cv2.cvtColor(binary_image,cv2.COLOR_BGR2GRAY)
    23. #彩色图像,进行RGB到灰度的转换
    24. edges_y, edges_x = np.where(binary_image < 127) ##h, w
    25. #选取有颜色(RGB < 127)点的坐标
    26. #直方图统计
    27. # plt.hist(edges_x,bins=1000)
    28. # plt.savefig("./3_edges_x.png")
    29. # plt.hist(edges_y,bins=1000)
    30. # plt.savefig("./3_edges_y.png")
    31. # Step 1 :使用X轴 先将图片 纵向分割成一条一条
    32. xdict = Counter(edges_x)
    33. #统计edges_x中各个元素的个数-可以反映出 图片像素点在X轴压缩后的分布情况
    34. x_black = sorted(xdict.keys())
    35. #排序
    36. #x_black中的元素,表示对应的y轴这列像素点存在黑色(RGB),反之不存在与black中的X轴对应的一列像素点是纯白色
    37. tmp=0
    38. lnum = 0
    39. n = 10
    40. for a in x_black:
    41. lnum = lnum + 1
    42. if tmp == a:
    43. tmp = tmp + 1
    44. else:
    45. #tmp 到 a之间的区域 是没有数据的,可以清除了
    46. # 由于上面的 127的选取会剪掉多余可用的部分,因此出需要在可用的数据部分基础上多保留 n个像素点,以确保可用部分不丢失
    47. # debug 显示框框,
    48. # image[0:, (tmp+n):(tmp+1+n), :] = (0, 0, 0) #debug
    49. # image[0:, (a-1-n):(a-n), :] = (0, 0, 0) #debug
    50. #清理 分割出来的脏背景
    51. image[0:, (tmp+n):(a-n), :] = (255, 255, 255)
    52. tmp = a + 1
    53. # 最后一条脏区域
    54. image[0:, (tmp+n):, :] = (255, 255, 255)
    55. # 兼容第一条脏区域
    56. image[0:, 0:n, :] = (255, 255, 255)
    57. # Step 2 : 使用Y轴 先将图片 横向分割 清理上下两个区域
    58. #取出最大,最小值即可
    59. ymin = min(edges_y)
    60. ymax = max(edges_y)
    61. yn = 7
    62. image[(ymax+yn):(ymax+1+yn), 0:, :] = (0, 0, 0) #debug
    63. image[(ymin-1-yn):(ymin-yn), 0:, :] = (0, 0, 0) #debug
    64. #清理 分割出来的脏背景
    65. image[(ymax+yn):, 0:, :] = (255, 255, 255)
    66. image[0:(ymin-yn), 0:, :] = (255, 255, 255)
    67. return image
    68. cv2.imwrite("./3_fenge.jpg",remove_the_blackborder("3_biankuang.jpg"))

    原始图像

    纵向清理

    纵向+横向清理

    上述算法在使用过程中,依然有bug,

    • 如果有大块的墨点,影响判断,
    • 图像的字迹太淡,会导致图片被清零

    下一步优化算法:

    1. 计算 一列 或者一行的 RGB avg然后,根据数据统计可以分析出边框,但是对于 图像这种差异不明显的图片,无法分离出;这样方法之实用与文字这种差异比较明显的场景

    1. import numpy as np
    2. import matplotlib.pyplot as plt
    3. import cv2
    4. #分割图片,提取每一个 方格字 其他的部分,设置成白色RGB==255
    5. def clean_Zang_background_by_Fengge(image):
    6. image = cv2.imread(image) #读取图片
    7. img = cv2.medianBlur(image, 5) #中值滤波,去除黑色边际中可能含有的噪声干扰
    8. #medianBlur( InputArray src, OutputArray dst, int ksize );
    9. #这里的src代表输入图像,dst代表输出图像,ksize 必须是正数且为奇数
    10. #该函数使用中值滤波器来平滑图像,可以消除图像中的小点,该值越大,则消除的点越大
    11. b = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) #调整裁剪效果
    12. #大于127 的像素点都处理成 255 白色
    13. #计算
    14. binary_image = b[1] #二值图--具有三通道
    15. #彩色图像: 有blue,green,red三个通道,取值范围均为0-255
    16. #灰度图:只有一个通道0-255,所以一共有256种颜色
    17. #二值图像:只有两种颜色,黑色和白色,二值化就是把图像的像素转变为0或者255,只有这
    18. 两个像素值。0白色 1黑色 。0是黑色,255是白色
    19. binary_image = cv2.cvtColor(binary_image,cv2.COLOR_BGR2GRAY)
    20. #彩色图像,进行RGB到灰度的转换
    21. # debug
    22. cv2.imwrite('3_xheibai.jpg',binary_image)
    23. #edges_y, edges_x = np.where(binary_image < 127) ##h, w
    24. #选取有颜色(RGB < 127)点的坐标
    25. # debug
    26. print(len(binary_image))
    27. print(binary_image)
    28. #xavgRGB = {}
    29. xNum=0
    30. xavyRGB=[]
    31. for ils in binary_image:
    32. xNum = xNum+1
    33. mavg =255 - np.mean(ils) #取反
    34. # 去除边框
    35. if(mavg > 250):
    36. mavg=0
    37. xavyRGB.append(mavg)
    38. # debug
    39. plt.bar(xNum, mavg)
    40. print(xNum)
    41. plt.savefig("./3_xavyRGB.png")
    42. clean_Zang_background_by_Fengge("0004_page_0004.jpg")

    原始图片和 y轴压缩后的avg柱状图

    考虑其他方法。

    验证使用的图片

  • 相关阅读:
    Pandas DataFrame 的可视化工具大全
    Linux 性能分析命令详解
    护网IP去重,去白名单
    【毕业设计】中文对话问答机器人系统 - python 深度学习
    Aspose.GIS 22.11.0 for .NET Crack
    MySQL和Oracle数据库引擎
    常用求解器安装
    vue2自定义指令及钩子函数
    众和策略:题材股什么意思?
    Python实现简易过滤删除数字的方法
  • 原文地址:https://blog.csdn.net/guiyuan_yelang/article/details/132777984