图像处理总结 持续更新ing~~
欢迎各位老师和同学提出更好的建议,直接评论即可
先贴一张从csdn上看到的CV技能树,我的想法是:CV方向可以试试,挺有趣
一.图像处理基础 图像 图像是由像素(pixel)组成的,像素是图像最小单位,是“小方格”,这些像素决定了图像在屏幕上的清晰度。
图像在计算机中的表达形式是矩阵
图像通常包括:二值图像,灰度图像,彩色图像
二值图像:
非黑(像素0)即白(像素255)
灰度图像:
黑白灰,灰度划分为256种不同的颜色,将彩色图像转换为灰度图是图像处理的最基本预处理操作。
彩色图像:
BGR图像(不同的器件可能不一样,人们习以为常说成RGB,而opencv中是RGB,甚至康佬曾说有一个器件是GBR),R红G绿B蓝这三原色按照不同的比例,作为三色通道,组成计算机所有的原色。
ROI区域
region of interest
是从图像中勾勒出需要处理的区域,广泛用于热点地图、人脸识别、图像分割等领域。
导包 1 2 3 import cv2import numpy as npimport matplotlib.pyplot as plt
opencv常用函数 安装过程请自行百度
读入图像
1 2 3 4 5 6 img = cv2.imread("文件名" ,参数)
显示图像
窗口等待
删除窗口
1 2 cv2.destroyAllWindows()
写入图片
读取像素
1 2 3 4 5 6 a = img[12 ,45 ] b = img[12 ,45 ,0 ] g = img[12 ,45 ,1 ] r = img[12 ,45 ,2 ]
修改图像
1 2 3 img[20 :100 ,30 :80 ] = [255 ,255 ,255 ]
形状、像素数目、类型
1 2 3 4 5 6 img.shape() img.size() img.dtype()
通道拆分与合并
1 2 3 4 5 6 7 8 9 b = img[:,:,0 ] g = img[:,:,1 ] r = img[:,:,2 ] b,g,r = cv2.split() b = cv2.split(img)[0 ] res = cv2.merge([b,g,r])
numpy常用函数 读取像素
1 2 3 b = img.item(12 ,45 ,0 ) g = img.item(12 ,45 ,1 ) r = img.item(12 ,45 ,2 )
修改像素
1 2 b = img.item((12 ,45 ),243 )
后续有常用的会继续添加
Matplotlib.pyplot常用函数 1 2 3 4 plt.subplot(2 ,2 ,1 ) plt.xticks() plt.yticks()
二.图像基本操作 (一)图像加法运算 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 1. 值>255 :结果对255 取模2. 值<=255 :图像1 +图像2 1. 值>255 :结果为255 2. 值<=255 :图像1 +图像2 img = cv2.imread("pic.jpg" ) test = img result1 = img + test result2 = cv2.add(img, test) cv2.imshow("org" , img) cv2.imshow("res1" , result1) cv2.imshow("res2" , result2) cv2.waitKey(0 ) cv2.destroyAllWindows()
参与运算的图像大小和类型必须一致
(二)图像融合 1 2 3 res = cv2.addWeighter(org,alpha,ano,beta,gamma)
两张融合的图像像素大小需要一致
(三)图像类型转换 图像处理通常需要将彩色图像转换为灰度图像再进行后续的操作
1 2 3 4 cv2.COLOR_BGR2GRAY cv2.COLOR_BGR2RGB cv2.COLOR_GRAY2BGR
(四)图像阈值化处理 1.通用函数 1 2 3 4 5 6 7 8 retval , dst = cv2.threshold(src,thresh,maxval,type )
2.阈值化 二值化或阈值化(Binarization)旨在提取图像中的目标物体,将背景以及噪声区分开来。通常会设定一个阈值T,通过T将图像的像素划分为两类:大于T的像素群和小于T的像素群。
二进制阈值化(cv2.THRESH_BINARY)
灰度值大于阈值:设其灰度值为max
灰度值小于阈值:0
反二进制阈值化(cv2.THRESH_BINARY_INV)
灰度值大于阈值:0
灰度值小于阈值:设其灰度值为255
截断阈值化(cv2.THRESH_TRUNC)
灰度值大于阈值:设为该阈值
灰度值小于阈值:不变
阈值化为0(cv2.THRESH_TOZERO)
灰度值大于阈值:0
灰度值小于阈值:不变
反阈值化为0(cv2.THRESH_TOZERO_INV)
灰度值大于阈值:不变
灰度值小于阈值:0
3.代码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import cv2import numpy as npimport matplotlib.pyplot as pltsrc = cv2.imread("test1.jpg" ) grayImg = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY) r , a = cv2.threshold(grayImg,127 ,255 ,cv2.THRESH_BINARY) r , b = cv2.threshold(grayImg,127 ,255 ,cv2.THRESH_BINARY_INV) r , c = cv2.threshold(grayImg,127 ,255 ,cv2.THRESH_TRUNC) r , d = cv2.threshold(grayImg,127 ,255 ,cv2.THRESH_TOZERO) r , e = cv2.threshold(grayImg,127 ,255 ,cv2.THRESH_TOZERO_INV) titles = ['GrayImg' ,'Binary' ,'Binary_inv' ,'Trunc' ,'Tozero' ,'Tozero_inv' ] images = [grayImg,a,b,c,d,e] for i in range (6 ): plt.subplot(2 ,3 ,i+1 ),plt.imshow(images[i],'gray' ) plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show() cv2.waitKey(0 ) cv2.destroyAllWindows()
4.运行结果
(五)图像腐蚀与膨胀 是两种基本的形态学 运算,主要用于图像中的极大区域和极小区域,包含两个输入对象:
二值图像、卷积核
形态学:主要针对二值图像
1.图像膨胀dilation(领域扩张) 运算符号:
定义:
该公式表示用B来对图像A进行膨胀处理,其中B是一个卷积模板或卷积核,其形状可以为正方形或圆形,通过模板B与图像A进行卷积计算,扫描图像中的每一个像素点,用模板元素与二值图像元素做“与”运算,如果都为0,那么目标像素点为0,否则为1。从而计算B覆盖区域的像素点最大值,并用该值替换参考点的像素值实现膨胀。
2.图像腐蚀erosion(领域蚕食) 运算符号:
定义:
该公式表示图像A用卷积模板B来进行腐蚀处理,通过模板B与图像A进行卷积计算,得出B覆盖区域的像素点最小值,并用这个最小值来替代参考点的像素值。
3.代码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import cv2from matplotlib import imageimport numpy as npimport matplotlib.pyplot as pltsrc = cv2.imread("test1.jpg" ,cv2.IMREAD_UNCHANGED) kernel = np.ones((5 ,5 ),np.uint8) erosion = cv2.erode(src,kernel) dilate = cv2.dilate(src,kernel) titles = ['source' ,'erosion' ,'dilate' ] images = [src,erosion,dilate] for i in range (3 ): plt.subplot(1 ,3 ,i+1 ),plt.imshow(images[i],'gray' ) plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show() cv2.waitKey(0 ) cv2.destroyAllWindows()
4.运行结果
(六)图像开闭梯度运算 1.概念 开 运 算 膨 胀 腐 蚀
图像被腐蚀后,去除了噪声,但是也压缩了图像;接着对腐蚀过的图像进行膨胀处理,可以去除噪声,并保留原有图像。
闭 运 算 腐 蚀 膨 胀
有助于关闭前景物体内部的小孔,或物体上的小黑点。
梯 度 运 算 膨 胀 腐 蚀
膨胀图像减去腐蚀图像的结果,得到图像的轮廓,其中二值图像1表示白色点,0表示黑色点。
2.通用函数
3.代码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import cv2import numpy as npimport matplotlib.pyplot as pltimg = cv2.imread("test1.jpg" ) kernel = np.ones((5 ,5 ),np.uint8) res1 = cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel) res2 = cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel) res3 = cv2.morphologyEx(img,cv2.MORPH_GRADIENT,kernel) titles = ["source" ,"open" ,"close" ,"grad" ] images = [img,res1,res2,res3] for i in range (4 ): plt.subplot(1 ,4 ,i+1 ),plt.imshow(images[i]) plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()
4.运行结果
(七)顶帽黑帽运算 1.概念 顶 帽 原 图 像 开 运 算
黑 帽 闭 运 算 原 图 像
2.通用函数
3.代码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import cv2import numpy as npimport matplotlib.pyplot as pltsrc = cv2.imread("test1.jpg" ) kernel = np.ones((10 ,8 ),np.uint8) res1 = cv2.morphologyEx(src,cv2.MORPH_TOPHAT,kernel) res2 = cv2.morphologyEx(src,cv2.MORPH_BLACKHAT,kernel) titles = ["src" ,"tophat" ,"blackhat" ] images = [src,res1,res2] for i in range (3 ): plt.subplot(1 ,3 ,i+1 ),plt.imshow(images[i]) plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()
4.运行结果
(八)灰度直方图(histogram) 1.概念 灰度直方图是灰度级的函数,描述的是图像中每种灰度级像素的个数,反映了每种灰度出现的频率。
横坐标:灰度级
纵坐标:灰度级出现的频率
对于连续图像,平滑地从中心的高灰度级变化到边缘的低灰度级。
2.matplotlib绘制直方图 1 2 3 4 import matplotlib.pyplot as plthist(数据源,像素级)
数据源必须是一维数组,通常要ravel()函数来拉直图像
像素级一般是256,表示[0,255]
代码实现 1 2 3 4 5 6 7 import cv2import numpy as npimport matplotlib.pyplot as pltsrc = cv2.imread("test1.jpg" ) plt.hist(src.ravel(),256 ) plt.show()
结果
(九)图像几何变换总结 关于plt画图出现和源文件不一致问题的修正:
1 2 3 src = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
新知识:仿射变换、透视变换
1.仿射变换 设 为输出图像坐标, 为输入图像坐标,仿射变换可以表示为:
对应矩阵为:
其中T有如下形式:
仿射变换函数接口:
1 2 3 4 5 6 7 8 9 warpAffine( InputArray src, 输入图像 OutputArray dst, 输出图像 InputArray M, 仿射计算矩阵 Size dsize, 输出图像大小 int flags = INIET_LINEAR, 插值方法 int borderMode = BORDER_CONSTANT, const Scalar& borderValue = Scalar() );
2.拓展:线性变换 设算子 ,对线性空间 上的任意元素 和 ,以及数域 中任意 ,都有:
可以合并为:
对于仿射变换来讲:
对坐标 和 进行线性变换:
令
令
则有:
【注】上面的过程证明了神经网络需要激活函数的原因
因为权重计算过程的本质就是矩阵的计算,而单纯的矩阵计算一定是线性变换,多层网络模型只是多个线性变换的叠加,其实可以表示为一个变换,如下:
所以神经网络为了拟合更加复杂的函数,必须添加非线性变换,即激活函数
只要是矩阵变换,就一定是线性变换
不过对于神经网络来说,传统表示会用添加1来进行维度对齐,则对于内存的利用率太低,故一般形式改为:
对应到图像处理中就是如下形式:
3.透视变换 透视变换(perspective transformation)是将物体重新投影到一个新的视角或成像平面,常用于机器人视觉导航研究中,由于相机视场与地面存在倾斜角使得物体成像产生畸变,通常使用透视变换实现对物体图像的校正。
透视变换作用域是三维坐标系 ,变换矩阵是一个3x3的矩阵。从另一个角度来说,仿射变换也可以看作是一种特殊的透视变换。
两条平行线仿射变换后仍然保持平行,但透视变换不保证这一点。
透视变换函数接口:
1 2 3 4 5 6 7 8 9 void warpPerspective( InputArray src, 源图像 OutputArray dst, 输出图像 InputArray M, 透视变换矩阵M:3x3 Size dsize, 输出图像尺寸 int flags=INTER_LINEAR, 插值方法标志 int borderMode=BORDER_CONSTANT, 像素边界外推方法标志 const Scalar& borderValue=Scalar() 填充边界使用的数值,默认为0 );
4.整体代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 import cv2import numpy as npimport matplotlib.pyplot as pltimg = cv2.imread("test1.jpg" ) image = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) M = np.float32([[1 ,0 ,80 ],[0 ,1 ,30 ]]) rows , cols = image.shape[:2 ] img1 = cv2.warpAffine(image,M,(cols,rows)) img2 = cv2.resize(image,(200 ,100 )) img3 = cv2.resize(image,None ,fx=1.2 ,fy=1.2 ) rows, cols, channel = image.shape M = cv2.getRotationMatrix2D((cols/2 , rows/2 ), 30 , 1 ) img4 = cv2.warpAffine(image, M, (cols, rows)) img5 = cv2.flip(image, 0 ) img6 = cv2.flip(image, 1 ) pts1 = np.float32([[50 ,50 ],[200 ,50 ],[50 ,200 ]]) pts2 = np.float32([[10 ,100 ],[200 ,50 ],[100 ,250 ]]) M = cv2.getAffineTransform(pts1,pts2) img7 = cv2.warpAffine(image, M, (rows,cols)) pts1 = np.float32([[56 ,65 ],[238 ,52 ],[28 ,237 ],[239 ,240 ]]) pts2 = np.float32([[0 ,0 ],[200 ,0 ],[0 ,200 ],[200 ,200 ]]) M = cv2.getPerspectiveTransform(pts1,pts2) img8 = cv2.warpPerspective(image,M,(200 ,200 )) titles = [ 'source' , 'shift' , 'reduction' , 'enlarge' , 'rotation' , 'flipX' , 'flipY' , 'affine' , 'transmission' ] images = [image, img1, img2, img3, img4, img5, img6, img7, img8] for i in range (9 ): plt.subplot(3 , 3 , i+1 ), plt.imshow(images[i], 'gray' ) plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()
5.运行结果
(十)图像灰度化处理 图像处理过程中,常常需要用到灰度图像、二值图像、HSV、HSI等颜色,OpenCV提供了cvtColor()函数实现这些功能。
1 2 3 4 5 dst = cv2.cvtColor(src,code,[,dst[,dstCn]) dst :输出图像,大小和深度与src一致 src :输入图像,需要进行颜色空间变换的原图像 code:转换的代码或标识 dstCn:目标图像通道数。值为0时,则由src和code决定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 import cv2 import numpy as np import matplotlib.pyplot as pltimg_BGR = cv2.imread("test1.jpg" ) img_RGB = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2RGB) img_GRAY = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2GRAY) img_HSV = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2HSV) img_YCrCb = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2YCrCb) img_HLS = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2HLS) img_XYZ = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2XYZ) img_LAB = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2LAB) img_YUV = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2YUV) titles = ['BGR' , 'RGB' , 'GRAY' , 'HSV' , 'YCrCb' , 'HLS' , 'XYZ' , 'LAB' , 'YUV' ] images = [img_BGR, img_RGB, img_GRAY, img_HSV, img_YCrCb, img_HLS, img_XYZ, img_LAB, img_YUV] for i in range (9 ): plt.subplot(3 , 3 , i+1 ), plt.imshow(images[i], 'gray' ) plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()
运行结果
(十一)图像傅里叶变换 基础知识去看信号与系统,直接上代码,不多bb
傅里叶变换主要是将时间域上的信号转变为频率域上的信号,用来进行图像降噪、图像增强等处理。
高频信号往往是图像中的边缘信号和噪声信号,而低频信号包含图像变化频繁的图像轮廓以及背景信号。
结果图像中,中心的图像表示低频信号,边缘的图像代表高频图像,需要注意的是,原图像和傅里叶变换结果的图像不是一一对应的。
快速傅里叶变换(FFT) 快速傅里叶变换是傅里叶变换的快速算法而已,主要是能减少运算量和存储开销,对于硬件实现特别有利。
作用:大大降低了运算量,使得让计算机处理信号成为可能。
Numpy实现傅里叶变换、逆变换 FFT包提供函数np.fft.fft2()对信号进行快速傅里叶变换
函数原型:
1 2 3 4 5 6 7 ff2(a,s=None ,axes=(-2 ,-1 ),norm=None ) ifft2(a,n=None ,axis=-1 ,norm=None )
代码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import cv2import numpy as npimport matplotlib.pyplot as pltsrc = cv2.imread("lena.jpg" ,cv2.IMREAD_GRAYSCALE) f = np.fft.fft2(src) fshift = np.fft.fftshift(f) res = np.log(np.abs (fshift)) ishift = np.fft.ifftshift(fshift) img = np.fft.ifft2(ishift) img = np.abs (img) titles = ["src" ,"fft" ,"ifft" ] images = [src,res,img] for i in range (3 ): plt.subplot(1 ,3 ,i+1 ) plt.imshow(images[i],'gray' ) plt.title(titles[i]) plt.xticks(),plt.yticks() plt.axis('off' ) plt.show()
运行结果
Opencv实现傅里叶变换、逆变换 opencv实现结果和numpy是一样的,但是opencv的是双通道的。通道1是结果实数部分,通道2是结果虚数部分,且输入图像要转换成np.float32 形式。
1 2 3 4 5 dst = cv2.dft(src,dst=None ,flags = None ,nonzeroRows=None )
注意,由于输出的频谱结果是一个复数,需要调用cv2.magnitude()函数将傅里叶变换的双通道结果转换为0到255的范围。
1 2 3 4 5 6 7 8 cv2.magnitude(x,y) cv2.idft(src[, dst[, flags[, nonzeroRows]]])
代码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import numpy as npimport cv2from matplotlib import pyplot as pltimg = cv2.imread("lena.jpg" , 0 ) dft = cv2.dft(np.float32(img), flags = cv2.DFT_COMPLEX_OUTPUT) dftshift = np.fft.fftshift(dft) res1= 20 *np.log(cv2.magnitude(dftshift[:,:,0 ], dftshift[:,:,1 ])) ishift = np.fft.ifftshift(dftshift) iimg = cv2.idft(ishift) res2 = cv2.magnitude(iimg[:,:,0 ], iimg[:,:,1 ]) titles = ["src" ,"Fourier" ,"Inverse Fourier" ] images = [img,res1,res2] for i in range (3 ): plt.subplot(1 ,3 ,i+1 ) plt.imshow(images[i],'gray' ) plt.title(titles[i]) plt.xticks(),plt.yticks() plt.axis('off' ) plt.show()
运行结果
(十二)图像量化、采样(project关键) 量化 自然界图像是模拟信号,只有将连续的信号离散化,图像转换为数字图像,才能进行下一步处理。
量化等级越多,图像层次越丰富,灰度分辨率越高,图像的质量也越好;量化等级越少,图像层次欠丰富,灰度分辨率越低,会出现图像轮廓分层的现象,降低了图像的质量。
1.操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 import cv2import numpy as npimport matplotlib.pyplot as pltsrc = cv2.imread("lena.jpg" ,cv2.IMREAD_UNCHANGED) height = src.shape[0 ] width = src.shape[1 ] new_img = np.zeros((height,width,3 ),np.uint8) for i in range (height): for j in range (width): for k in range (3 ): if src[i, j][k] < 32 : gray = 0 elif src[i, j][k] < 64 : gray = 32 elif src[i, j][k] < 96 : gray = 64 elif src[i, j][k] < 128 : gray = 96 elif src[i, j][k] < 160 : gray = 128 elif src[i, j][k] < 192 : gray = 160 elif src[i, j][k] < 224 : gray = 192 else : gray = 224 new_img[i, j][k] = np.uint8(gray) titles = ["src" ,"process" ] images = [src,new_img] for i in range (2 ): plt.subplot(1 ,2 ,i+1 ),plt.imshow(images[i],'gray' ) plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()
2.运行结果
3.K-Means聚类量化处理(拓展) 聚类是在事先并不知道任何样本标签的情况下,通过数据之间的内在关系把样本划分为若干类别,使得同类别样本之间的相似度高,不同类别之间的样本相似度低。
KMenas的优点:
高效可伸缩,计算复杂度为 接近于线性(N是数据量,K是聚类总数,t是迭代轮数)。
收敛速度快,原理相对通俗易懂,可解释性强。
KMeans也有一些明显的缺点:
受初始值和异常点影响,聚类结果可能不是全局最优而是局部最优。
K是超参数,一般需要按经验选择
样本点只能划分到单一的类中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 import cv2import numpy as npimport matplotlib.pyplot as pltimg = cv2.imread("test1.jpg" ) data = img.reshape((-1 ,3 )) data = np.float32(data) criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10 , 1.0 ) flags = cv2.KMEANS_RANDOM_CENTERS compactness, labels, centers = cv2.kmeans(data, 4 , None , criteria, 10 , flags) centers = np.uint8(centers) res = centers[labels.flatten()] dst = res.reshape((img.shape)) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) dst = cv2.cvtColor(dst, cv2.COLOR_BGR2RGB) titles = ["src" ,"process" ] images = [img, dst] for i in range (2 ): plt.subplot(1 ,2 ,i+1 ), plt.imshow(images[i], 'gray' ), plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()
4.运行结果
采样 Image Sampling (项目关键,不过网上讲的不太系统,准备去图书馆转一圈顺便还书
(人工智能安全太遥远了
将一幅连续图像在空间上分割成M×N个网格,每个网格用一个亮度值或灰度值来表示。
图像采样的间隔越大,所得图像像素数越少,空间分辨率越低,图像质量越差,甚至出现马赛克效应 ;相反,图像采样的间隔越小,所得图像像素数越多,空间分辨率越高,图像质量越好,但数据量会相应的增大。
1.全图采样示例代码 网上的代码存在一个问题,当图像的长度和宽度不能被采样区域整除时,输出图像的最右边和最下边的区域没有被采样处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 import cv2import cv2import numpy as npimport matplotlib.pyplot as pltsrc = cv2.imread("lena.jpg" ) height = src.shape[0 ] width = src.shape[1 ] numHeight = int (height/109 ) numWidth = int (width/109 ) new_src = np.zeros((height,width,3 ),np.uint8) for i in range (109 ): y = i*numHeight for j in range (109 ): x = j*numWidth b = src[y,x][0 ] g = src[y,x][1 ] r = src[y,x][2 ] for n in range (numHeight): for m in range (numWidth): new_src[y+n,x+m][0 ] = np.uint8(b) new_src[y+n,x+m][1 ] = np.uint8(g) new_src[y+n,x+m][2 ] = np.uint8(r) titles = ["src" ,"process" ] images = [src,new_src] for i in range (2 ): plt.subplot(1 ,2 ,i+1 ) plt.imshow(images[i],'gray' ) plt.xticks([]),plt.yticks([]) plt.show()
2.结果
(十三)位平面分解 概念 将 灰度图像中处于统一比特位上的二进制像素值进行组合,得到一副二进制图像 ,该图像被称为灰度图像的一个位平面,这个过程被称为位平面分解。在组成一张图的过程中,高位的图往往起到了更加关键的作用。
常用的是二进制位平面分解技术(BBD)
图示
代码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import cv2import numpy as npimport matplotlib.pyplot as pltimg = cv2.imread("lena.png" ,0 ) h , w = img.shape x = np.zeros((h,w,8 ),dtype=np.uint8) for i in range (8 ): x[:,:,i] = 2 ** i r = np.zeros((h,w,8 ),dtype=np.uint8) for i in range (8 ): r[:,:,i] = cv2.bitwise_and(img,x[:,:,i]) mask = r[:,:,i] > 0 r[mask] = 255 cv2.imwrite("your file path" +str (i)+".png" ,r[:,:,i]) cv2.waitKey(0 ) cv2.destroyAllWindows()