当前位置: 首页 > news >正文

Python 图片处理笔记

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

分割清楚脏背景

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

原始图像

纵向清理

纵向+横向清理

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

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

下一步优化算法:

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

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

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

考虑其他方法。

验证使用的图片

http://www.lryc.cn/news/171193.html

相关文章:

  • SpringCloud Ribbon--负载均衡 原理及应用实例
  • Redis的介绍以及简单使用
  • ad18学习笔记十二:如何把同属性的元器件全部高亮?
  • SpringSecurity 核心过滤器——SecurityContextPersistenceFilter
  • 反转单链表
  • 加速新药问世,药企如何利用云+网的优势?
  • C++中string对象之间比较、char*之间比较
  • MVVM模式理解
  • js常用的数组处理方法
  • [Document]VectoreStoreToDocument开发
  • 【LeetCode-简单题】225. 用队列实现栈
  • 数据预处理方式合集
  • 【前端】jquery获取data-*的属性值
  • GB28181学习(五)——实时视音频点播(信令传输部分)
  • 单例模式(饿汉模式 懒汉模式)与一些特殊类设计
  • 133. 克隆图
  • 交流耐压试验目的
  • 使用 YCSB 和 PE 进行 HBase 性能压力测试
  • 正则表达式相关概念及不可见高度页面的获取
  • 深入学习 Redis - 分布式锁底层实现原理,以及实际应用
  • Hive行转列[一行拆分成多行/一列拆分成多列]
  • TypeScript系列之类型 string
  • 【C++】动态内存管理 ③ ( C++ 对象的动态创建和释放 | new 运算符 为类对象 分配内存 | delete 运算符 释放对象内存 )
  • AMS爆炸来袭,上线即巅峰
  • 是面试官放水,还是公司实在是太缺人?这都没挂,华为原来这么容易进...
  • 怒刷LeetCode的第2天(Java版)
  • AUTOSAR汽车电子嵌入式编程精讲300篇-车载CAN总线网络的异常检测(续)
  • mojo安装
  • 【探索Linux】—— 强大的命令行工具 P.8(进程地址空间)
  • vue3 - Element Plus 切换主题色及el-button hover颜色不生效的解决方法