图像识别之图片处理基础内容

简介: Python call()方法, Python 类中一个非常特殊的实例方法,即 call()。该方法的功能类似于在类中重载 () 运算符,使得类实例对象可以像调用普通函数那样,以“对象名()”的形式使用。

课程连接

项目链接


1.python 的__call__()方法



Python call()方法, Python 类中一个非常特殊的实例方法,即 call()。该方法的功能类似于在类中重载 () 运算符,使得类实例对象可以像调用普通函数那样,以“对象名()”的形式使用。


就相当于把可以不用先实例化然后再调用函数,直接运行即可!

class Worker:
    # 定义__call__方法
    def __call__(self, name, add):
        print("调用__call__()方法", name, add)
    def call(self,name,add):
        print('调用call函数:',name,add)
name = "PaddlePaddler"
add = "http://aistudio.baidu.com"
work = Worker()
work(name, add)
work.call(name, add)


调用__call__()方法 PaddlePaddler http://aistudio.baidu.com
调用call函数: PaddlePaddler http://aistudio.baidu.com


2.图像基础知识



2.1图像基本数据结构


在计算机中, 图像是由一个个像素点组成,像素点就是颜色点,而颜色最简单的方式就是用RGB或RGBA表示 。


5cc5e7fbbc3bf1d635d10a2601a0ccb2.png


RGB(图1)


c1a4a3774de9dfe15b6cd19014307ed7.png


RGB(图2)


如果有A通道就表明这个图像可以有透明效果。

R,G,B每个分量一般是用一个字节(8位)来表示,所以图(1)中每个像素大小就是3 * 8=24位图, 而图(2)中每个像素大小是4 * 8=32位。


白话:

那么图一的大小就是(5 * 5 * 24 / 8 = 25 * 3 = 75KB )

图二的大小就是(5 * 5 * 32 / 8 = 25 * 4 = 100KB)

相当于大小就是像素点数量 * 通道数


2.2图像y方向正立或倒立


图像是二维数据,数据在内存中只能一维存储,二维转一维有不同的对应方式。比较常见的只有两种方式: 按像素“行排列”从上往下或者从下往上。


cb90944da99486533a7ab0b16913e7ed.png


如图所示的图像有9个像素点,如果从上往下排列成一维数据是(123456789), 如果是从下往上排列则为(789456123)。

只所以会有这种区别是因为,前一种是以计算机图形学的屏幕坐标系为参考(左上为原点,y轴向下 ),而另后一种是以标准的数学坐标系为参考(左下为原点,y轴向上)。这两个坐标系只是y值不一样,互相转换的公式为:


y2 = height-1-y1


y1,y2分别为像素在两个坐标系中的y坐标,height为图像的高度。


不过好像只有bmp图片格式以及windows下的GDI,GDI+是从下往上排列,其它比如DirectX,OpenGL,Cocoa(NSImage, UIImage),OpenCV等都是从上往下排列。


2.3 RGB排列顺序


不同图形库中每个像素点中RGBA的排序顺序可能不一样。上面说过像素一般会有RGB,或RGBA四个分量,那么在内存中RGB的排列就有6种情况,如下:


  • RGB
  • RBG
  • GRB
  • GBR
  • BGR
  • BRG


RGBA的排列有24种情况,这里就不全部列出来了。


不过一般只会有RGB,BGR, RGBA, RGBA, BGRA这几种排列据。 绝大多数图形库或环境是BGR/BGRA排列,cocoa中的NSImage或UIImage是RGBA排列。


2.4像素32位对齐


如果是RGB24位图,会存在一个32位对齐的问题——

在x86体系下,cpu一次处理32整数倍的数据会更快,图像处理中经常会按行为单位来处理像素。24位图,宽度不是4的倍数时,其行字节数将不是32整数倍。这时可以采取在行尾添加冗余数据的方式,使其行字节数为32的倍数。

比如,如果图像宽为5像素,不做32位对齐的话,其行位数为24*5=120,120不是32的倍数。是32整数倍并且刚好比120大的数是128,也就只需要在其行尾添加1字节(8位)的冗余数据即可。(一个以空间换时间的例子)

有个公式可以轻松计算出32位对齐后每行应该占的字节数


byteNum = ((width * 24 + 31) & ~31)>>3;


注意结果是字节数,如果想知道位数,还得x8


3.图片格式的必要性



如果将图像原始格式直接存储到文件中将会非常大,比如一个50005000 24位图,所占文件大小为50005000*3字节=71.5MB, 其大小非常可观。如果用zip或rar之类的通用算法来压缩像素数据,得到的压缩比例通常不会太高,因为这些压缩算法没有针对图像数据结构进行特殊处理。于是就有了jpeg,png等格式,同样是图像压缩算法jpeg和png也有不同的适用场景,具体在下文再阐述。


1d151341a0e5d3e886745032b4ac5e66.png


jpeg,png文件之于图像,就相当于zip,rar格式之于普通文件(用zip,rar格式对普通文件进行压缩)。


3.1BMP格式


bmp格式没有压缩像素格式,存储在文件中时先有文件头、再图像头、后面就都是像素数据了,上下颠倒存储。

用windows自带的mspaint工具保存bmp格式时,可以发现有四种bmp可供选择:


  • 单色: 一个像素只占一位,要么是0,要么是1,所以只能存储黑白信息
  • 16色位图: 一个像素4位,有16种颜色可选
  • 256色位图: 一个像素8位,有256种颜色可选
  • 24位位图: 就是图(1)所示的位图,颜色可有2^24种可选,对于人眼来说完全足够了。

简单起见,只详细讨论最常见的24位图的bmp格式。


3.2JPEG格式


  • jpeg是有损压缩格式, 将像素信息用jpeg保存成文件再读取出来,其中某些像素值会有少许变化。在保存时有个质量参数可在[0,100]之间选择,参数越大图片就越保真,但图片的体积也就越大。一般情况下选择70或80就足够了。
  • jpeg没有透明信息。
  • jpeg比较适合用来存储相机拍出来的照片,这类图像用jpeg压缩后的体积比较小。其使用的具体算法核心是离散余弦变换、Huffman编码、算术编码等技术,有兴趣的同学可以在网上找一大堆资料,本文就不详细介绍了。


3.3PNG格式


  • png是一种无损压缩格式, 压缩大概是用行程编码算法。
  • png可以有透明效果。
  • png比较适合适量图,几何图。 比如本文中出现的这些图都是用png保存,比用joeg保存体积要小。


3.4GIF格式


上面提到的bmp,jpeg,png图片都只有一帧,而gif可以保存多帧图像,如图所示


8d33ee694b0142fa6e37c555656e1451.png


3.4WebP编码


Webp是一种高效的图像编码方式,由谷歌推出,开源免费。其图像压缩效率相比jpg可以提升一倍性能。一般保存需要设置压缩因子。


4.常用库



4.1Numpy


Numpy对多维矩阵A的操作一般有:


A.shape #HWC
type(A) #numpy.array
A.dtype() #uint8,
float…
np.min(A), np.max(A) #最值


4.2 CV2


读取BGR,通道HWC,范围[0,255] ,类型uint8; 图像类型numpy.ndarray;


4.3 PIL,Pillow, Pillow-SIMD


读取RGB,通道HWC,范围[0,255],类型uint8;图像类型PngImageFile (np.array, Image.fromarray直接与numpy互相转换)

有.mode方法—rgb信息


4.4 Matplotlib


读取RGB,通道HWC,范围[0,1] ,类型float;图像类型numpy.ndarray


4.5Skimage


读取RGB,通道HWC,范围[0,255],类型uint8;图像类型numpy.ndarray

有.mode方法—rgb信息


比较特殊,读取的时候image= io.imread(‘test.jpg’,as_grey=False);

彩图是uint8,[0,255];灰度图float,[0,1];

彩图resize变成float,[0,1];

较混乱,不适用。。。


5.常见操作



5.1CV2

默认读取为三通道彩图,可通过参数更改为单通道灰度图


5.2 显示


Matplotlib最主要目的是用来绘图:

将numpy数组格式的RGB图像显示;

float类型的图像,范围0-1;如果是uint8图像,范围是0-255;


import cv2
import numpy
img = cv2.imread('1.png')
img_gray = cv2.imread('1.png', 0)
print('三通道:', img.shape)
print('单通道灰度图:', img_gray.shape)
三通道: (153, 300, 3)
单通道灰度图: (153, 300)


通过shape获得数组的维度,很明显单通道的只有一维。


import matplotlib.pyplot as plt
# 显示图片
# plt.imshow(img[..., -1::-1])  # 因为opencv读取进来的是bgr顺序,而imshow需要的是rgb顺序,因此需要先反过来,也可以plt.imshow(img[:,:,::-1])
plt.imshow(img_gray)
plt.show()


20210302231626491.png


from PIL import Image
# PIL, Pillow, Pillow-SIMD
img = Image.open('1.png')
plt.imshow(img)
plt.show()

2021030223164324.png


img = plt.imread('1.png')
plt.imshow(img)
plt.show()


20210302231647313.png


5.3 转换


主要是通过numpy的transpose操作,修正RGB,BGR;

例如:

a是rgb图像,那么

a[::-1],a[:,::-1],a[:,:,::-1]分别是X轴的镜像,Y轴的镜像,BGR转换为RGB;


opencv相关图像操作;
img_gray = cv2.cvtColor(img,
cv2.COLOR_BGR2GRAY) # BGR转灰度
img_bgr = cv2.cvtColor(img_gray,
cv2.COLOR_GRAY2BGR) # 灰度转BRG
img_rgb = cv2.cvtColor(img_gray,
cv2.COLOR_GRAY2RGB) # 灰度转RGB
b,g,r = cv2.split(img) #bgr图像分离三个通道
img2 = cv2.merge([r,g,b]) #merge成rgb图像
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # BGR转灰度
plt.imshow(img_gray)
plt.show()


20210302231706501.png

PIL相关图像操作:
img = Image.open('examples.png')
img_gray = image.convert(‘L’)
img_color = img_gray.convert(‘RGB’)
PIL与numpy格式转换操作:
numpy.asarray()
Image.fromarray()


如果是pil转opencv,记得需要通过copy命令得到的才可以进行cv2操作,不然会有bug。


PIL类型,尺寸信息,通过.size方法,得到WH;


Numpy类型,通过shape方法,得到HWC


注:如果是PIL自己的类型,得到尺寸信息要使用.size方法


print image.size #width height


同样进行resize操作,顺序也是wh;


img2_resize = img2.resize((960,540))


img2_resize.save(‘test1.jpg’)


而如果使用cv2操作,顺序也是wh;


img3_resize = cv2.resize(img3, (960,540))


cv2.imwrite(‘test2.jpg’, img3_resize)


但如果放在numpy里面,调用shape方法,得到的是HWC;


5.4 保存


PIL

#直接save方法
img = Image.open('examples.png')
img.save('examples2.png')
img_gray = img.convert('L')
img_gray.save('examples_gray.png') # 不管是灰度还是彩色,直接用save函数保存就可以,但注意,只有PIL格式的图片能够用save函数


CV2


#cv2.imwrite
import cv2
img = cv2.imread('examples.png') # 这是BGR图片
cv2.imwrite('examples2.png', img) # 这里也应该用BGR图片保存,这里要非常注意,因为用pylab或PIL读入的图片都是RGB的,如果要用opencv存图片就必须做一个转换
img_gray = cv2.cvtColor(img,
cv2.COLOR_BGR2GRAY)
cv2.imwrite('examples_gray.png', img_gray)


白话


里面涉及了图片的读取,基本定义等内容还涉及了一些数据的处理,特别是numpy数据处理时容易报错,需要格外注意!!!

这里只是基础但是需要认真的品读,不然以后麻烦呦!!!

相关实践学习
基于函数计算实现AI推理
本场景基于函数计算建立一个TensorFlow Serverless AI推理平台。
目录
相关文章
|
4月前
|
机器学习/深度学习 人工智能 数据处理
AI技术可以自动识别图像
在现代社会,人工智能已经成为了科技发展的重要驱动力。尤其是在众多领域中,AI技术的应用为人们的生活带来了极大的便利。其中,AI在图像识别方面的应用尤为突出,无论是在安防、医疗、教育,还是在日常生活中的方方面面,都有着广泛的应用。
58 3
|
9月前
|
人工智能 程序员
仅仅10秒,AI 能将你的静态图片转换成视频
仅仅10秒,AI 能将你的静态图片转换成视频
1228 0
仅仅10秒,AI 能将你的静态图片转换成视频
|
4月前
|
人工智能 算法
AI常用的人脸图像库
【1月更文挑战第2天】
AI常用的人脸图像库
|
11月前
|
机器学习/深度学习 人工智能 自然语言处理
「模型即服务AI」1分钟调用SOTA人脸检测,同时搭建时光相册小应用—【OpenVI—代码解读系列】
最近有两个计算机应用发展的方向正在潜移默化的汇拢中:1.)模型即服务 2.)人工智能(AI)。它们的会师正逐渐形成模型即服务AI热潮。 近几年模型即服务一直被人津津乐道,这是提升AI编程效率、加速AI创新应用的大趋势。人工智能领域近几年非常火热,基于AI的行业创新应用层出不穷,尤其今年的AI绘画又大有元年之势,相应介绍可查阅《人工智能内容生成元年—AI绘画原理解析》。如下章节将重点介绍如何通过模型即服务来完成AI功能调用以及相应AI应用搭建。
1276 3
「模型即服务AI」1分钟调用SOTA人脸检测,同时搭建时光相册小应用—【OpenVI—代码解读系列】
|
12月前
|
机器学习/深度学习 编解码 自然语言处理
PAI-Diffusion中文模型全面升级,海量高清艺术大图一键生成
本文主要介绍-Diffusion中文模型大幅升级,本文详细介绍PAI-Diffusion中文模型的新功能和新特性。
PAI-Diffusion中文模型全面升级,海量高清艺术大图一键生成
|
12月前
|
机器学习/深度学习 文字识别 自然语言处理
CCIG 2023 从视觉-语言模型到智能文档图像处理
最近,中国图像图形大会(CCIG 2023)在苏州成功结束。本次大会以“图像图形·向未来”为主题,由中国科学技术协会指导,中国图像图形学学会主办,苏州科技大学承办。
|
人工智能 开发框架 缓存
AI视觉实战1:实时人脸检测
AI在视觉领域最常用的就是人脸检测、人脸识别、活体检测、人体与行为分析、图像识别、图像增强等,而且目前都是比较成熟的技术,不论商业化的Paas平台还是开源的模型,都几乎一抓一大把。
152 0
|
存储 人工智能 JSON
图像识别项目讲解及使用说明 | 学习笔记
快速学习图像识别项目讲解及使用说明
535 0
图像识别项目讲解及使用说明 | 学习笔记
|
机器学习/深度学习 存储 自然语言处理
【技术白皮书】第一章:OCR智能文字识别新发展——深度学习的文本信息抽取
什么是基于深度学习的文本信息抽取? **信息抽取 (Information Extraction)** 是把原始数据中包含的信息进行结构化处理,变成表格一样的组织形式。输入信息抽取系统的是原始数据,输出的是固定格式的信息点,即从原始数据当中抽取有用的信息。信息抽取的主要任务是将各种各样的信息点从原始数据中抽取出来。然后以统一的形式集成在一起,方便后序的检索和比较。由于能从自然语言中抽取出信息框架和用户感兴趣的事实信息,无论是在信息检索、问答系统还是在情感分析、文本挖掘中,信息抽取都有广泛应用。随着深度学习在自然语言处理领域的很多方向取得了巨大成功......
【技术白皮书】第一章:OCR智能文字识别新发展——深度学习的文本信息抽取
|
编解码 人工智能
使用视觉AI技术提高图片质量的几种方法
通过视觉AI 技术来提高图片的质量
513 0
使用视觉AI技术提高图片质量的几种方法