包括一些Opencv的基本示例代码,方便以后查阅。
解决python调用TensorFlow时出现FutureWarning: Passing (type, 1) or ‘1type’ as a synonym of type is deprecate https://blog.csdn.net/bigdream123/article/details/99467316 python Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA https://blog.csdn.net/wukai0909/article/details/97306316
#注意tensorflow的输出格式和平常不同 import tensorflow as tf hello = tf.constant("hello tf!") sess = tf.Session() print(sess.run(hello))①JPG的压缩:有损压缩
import cv2 srcImage = cv2.imread("E:\\pictures\\12.jpg",1) cv2.imwrite("srcImage.jpg",srcImage,[cv2.IMWRITE_JPEG_QUALITY,0]) #数字0表示压缩的比例,范围是0-100,0是最高的压缩比,图像效果最差②PNG的压缩:无损压缩且具有透明度属性
import cv2 srcImage = cv2.imread("E:\\pictures\\12.jpg",1) cv2.imwrite("srcImage.png",srcImage,[cv2.IMWRITE_PNG_COMPRESSION,0]) #数字0表示压缩的比例,范围是0-9,0是最低的压缩比,图像效果最好①对于RGB图像 eg.一个图像1.14M = 7205473*8 bit/8 (B) 含义:宽×高×三个像素通道×每个颜色变量是八位的 / 8(转化为字节要除8) ②对于PNG图像 除了RGB三个通道,还要加上透明度alpha 通道
1.tensorflow的本质是 = tensor + graphs (tensor是张量、数据的意思,op即option操作运算,graphs是计算图、数据操作的意思,) 2.Session是计算的核心,可以理解为一个运算的交互环境 3.在上一节中,我们Session之后没有进行其他的操作,正常情况下是要close的:sess.close() 若不想这么麻烦,可以这样操作:
import tensorflow as tf data1 = tf.Variable(10,name='var') init = tf.global_variables_initializer() sess = tf.Session() with sess: sess.run(init) print(sess.run(data1))①常量的四则运算
import tensorflow as tf data1 = tf.constant(6) data2 = tf.constant(2) dataAdd = tf.add(data1,data2) #加 dataMul = tf.multiply(data1,data2) #乘 dataSub = tf.subtract(data1,data2) #减 dataDiv = tf.divide(data1,data2) #除 with tf.Session() as sess: print(sess.run(dataAdd)) print(sess.run(dataMul)) print(sess.run(dataSub)) print(sess.run(dataDiv)) print('end!') # 输出: # 8 # 12 # 4 # 3.0 # end!②常量与变量的四则运算 eval()方法:用于直接输出,相当于获取了一个默认的session,然后执行run的操作
import tensorflow as tf data1 = tf.constant(6) data2 = tf.Variable(2) dataAdd = tf.add(data1,data2) #加 dataCopy = tf.assign(data2,dataAdd) # dataAdd赋值给data2 init = tf.global_variables_initializer() with tf.Session() as sess: sess.run(init) print('sess.run(dateCopy)',sess.run(dataCopy)) #将8赋给data2 print('dataCopy.eval()',dataCopy.eval()) #data2+dataAdd:8+6=14 print('tf.get_default_session',tf.get_default_session().run(dataCopy))#14+6=20 print('end!')①tf.placeholder(dtype, shape=None, name=None) TensorFlow中的占位符,用于传入外部数据。 参数:dtype:数据类型;shape:数据的维度,默认为None,表示没有限制;name:名称 示例:
import tensorflow as tf data1 = tf.placeholder(tf.float32) data2 = tf.placeholder(tf.float32) dataAdd = tf.add(data1,data2) with tf.Session() as sess: print(sess.run(dataAdd,feed_dict={data1:6,data2:2})) #1.张量dataAdd 2.语法:data(feed_dict={参数1:6,参数2:2})②tensorflow中的矩阵运算 矩阵的定义:[[ 6,6 ]]表示一行两列的数据,外层的[ ]表示行,里层的[ ]表示列
import tensorflow as tf data1 = tf.constant([[6,6]]) data2 = tf.constant([[2],[2]]) data3 = tf.constant([[3,3]]) data4 = tf.constant([[1,2],[3,4],[5,6]]) print(data4.shape) #打印该矩阵的维度 3行两列 with tf.Session() as sess: print(sess.run(data4)) #打印整个矩阵 print(sess.run(data4[0])) #打印矩阵第一行 print(sess.run(data4[:,0])) #打印矩阵第一列 print(sess.run(data4[0,1])) #打印矩阵第一行第二列的元素 # 输出: # 输出: # (3, 2) # [[1 2] # [3 4] # [5 6]] # [1 2] # [1 3 5]注意矩阵乘法matmul()和multiply()两种方法的不同
import tensorflow as tf data1 = tf.constant([[6,6]]) data2 = tf.constant([[2],[2]]) data3 = tf.constant([[3,3]]) data4 = tf.constant([[1,2],[3,4],[5,6]]) matMul = tf.matmul(data1,data2) matMul2 = tf.multiply(data1,data2) matAdd = tf.add(data1,data3) with tf.Session() as sess: print(sess.run(matMul)) #矩阵相乘1*2 * 2*1 = 1*1 print(sess.run(matMul2)) # 矩阵相乘1*2 * 2*1 = 2*2 print(sess.run(matAdd)) #矩阵相加 #通过中括号的方式可以一次打印多个值 print(sess.run([matMul,matAdd])) # 输出: # [[24]] #[[12 12] # [12 12]] # [[9 9]] # [array([[24]]), array([[9, 9]])]①特殊矩阵的初始化
import tensorflow as tf mat1 = tf.zeros([2,3]) #设2*3的矩阵元素全为0 mat2 = tf.ones([3,2]) #设3*2的矩阵元素全为1 mat3 = tf.fill([2,3],15) #填充2*3的矩阵元素全为15 with tf.Session() as sess: print(sess.run(mat1)) print(sess.run(mat2)) print(sess.run(mat3))②linspace方法将区间取等分,zeros_like表示矩阵取相同的维度
mat1 = tf.constant([[2],[3],[4]]) mat2 = tf.zeros_like(mat1) #表示mat2矩阵和mat1矩阵的维度一样 mat3 = tf.linspace(0.0,2.0,11) #矩阵的元素在0-2之间等分 mat4 = tf.random_uniform([2,3],-1,2) #表示定义一个2*3的矩阵,元素在-1到2区间随机取输出:
resize()函数,第一个参数为源图,第二个参数为要缩放的宽和高,插值的类型。
import cv2 img = cv2.imread("E:\\pictures\\4.jpg",1) imgInfo = img.shape print(imgInfo) height = imgInfo[0] width = imgInfo[1] mode = imgInfo[2] #存放方式,即通道数 dstHeight = int(height*0.5) dstWidth = int(width*0.5) dst = cv2.resize(img,(dstWidth,dstHeight)) cv2.imshow("dst",dst) print(dst.shape) cv2.waitKey(0) # 输出: # (434, 650, 3) # (217, 325, 3)输出格式:高度(行)、宽度(列)、通道数
https://blog.csdn.net/csdnforyou/article/details/82315683 ①最近邻域插值法 说明:假设原图src:1020 效果图dst:510,则效果图由原图缩放而来,dst上的一点(1,2)对应于src上的(2,4),设dst上的像素点x2,y2,src上的像素点x1,y1,计算公式为: x1 = x2 (src 行 / 目标行)即:x1 = x2(10/5)= 12 = 2 y1 = y2 (src 列 / 目标列)即:y1 = y2(20/10)= 22 = 4 若计算得一像素点为12.3,则自动取12 ②双线性插值法 上图中原图中只有(15,22),(15,23),(16,22),(16,23)四个点,目标图像中新增了(15.2,22.3)这个点,双线性差值法则是根据这个新的点的周围四个点来确定这个点的值, A1=20%上 + 80%下;B1 = 30%左 + 70%右 最终点的确定:A130%+A270% B120% + B280%
前面已经掌握了算法的原理和图片缩放得API:resize函数,这里看下算法得源码
import cv2 import numpy as np img = cv2.imread("E:\\pictures\\4.jpg",1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] dstHeight = int(height/2) dstWidth = int(width/2) dst = np.zeros((dstHeight,dstWidth,3),np.uint8) #初始化,以便下面像素赋值 for i in range(0,dstHeight): #行 for j in range(0,dstHeight): #列 iNew = int(i*(height*1.0/dstHeight)) jNew = int(j*(width*1.0)/dstWidth) dst[i,j] = img[iNew,jNew] cv2.imshow("dst",dst) print(dst.shape) cv2.waitKey(0) # 输出: # (217, 325, 3)举例:剪切图像x轴100-200,y轴100-300
import cv2 img = cv2.imread("E:\\pictures\\4.jpg",1) imgInfo = img.shape dst = img[100:200,100:300] cv2.imshow("dst",dst) print(dst.shape) cv2.waitKey(0) # 输出:(100, 200, 3)①示例程序
import cv2 import numpy as np img = cv2.imread("E:\\pictures\\4.jpg",1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] matShift = np.float32([[1,0,100],[0,1,200]]) #2*3的偏移矩阵 dst = cv2.warpAffine(img,matShift,(height,width)) cv2.imshow("dst",dst) cv2.waitKey(0)②API介绍:warpAffine() 就拿上面的程序为例:[[1,0,100],[0,1,200]]是23的矩阵,拆分成22和21的两个矩阵,假设A是22的矩阵,即[[1,0], [0,1]],B是21的矩阵,即[[100],[200]],C是x和y。根据公式:AC+B = [[1x+0y],[0x+1y]]+[[100],[200]] = [[x+100],[y+200]] ③用算法原理编程:将原图往右移动100个像素 PS:先将dst初始化为黑色,因为是将图像右移100个像素,所以行不变,列改变,即先将dst的列先加100,再将原图dst的(列-100)再赋值给dst
import cv2 import numpy as np img = cv2.imread("E:\\pictures\\4.jpg",1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] dst = np.zeros((height,width,3),np.uint8) #初始化,以便下面像素赋值 for i in range(0,height): #行 for j in range(0,width-100): #列 dst[i,j+100] = img[i,j] cv2.imshow("dst",dst) cv2.waitKey(0)①步骤:①创建一个足够大的“画板”②将一副图像分别从前向后、从后向前绘制③绘制中心分割线 ②程序
import cv2 import numpy as np img = cv2.imread("E:\\pictures\\4.jpg",1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] deep = imgInfo[2] #图像的通道数 newImgInfo = (height*2,width,deep) #创建一个画板 dst = np.zeros(newImgInfo,np.uint8) #初始化,以便下面像素赋值 for i in range(0,height): #行 for j in range(0,width): #列 dst[i,j] = img[i,j] #先绘制上半部分 #因为是上下镜像,所以x不变,y*2 #下半部分图像坐标,x不变,y=2*h-y-1 dst[height*2-i-1,j] = img[i,j] for i in range(0,width): dst[height,i] = (0,0,255) #绘制中心分割线 cv2.imshow("dst",dst) cv2.waitKey(0)参考图片位移
import cv2 import numpy as np img = cv2.imread("E:\\pictures\\4.jpg",1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] matScale = np.float32([[0.5,0,0],[0,0.5,0]]) dst = cv2.warpAffine(img,matScale,(int(width/2),int(height/2))) cv2.imshow("dst",dst) cv2.waitKey(0)输出:
①API:getRotationMatrix2D()介绍:第一个参数:旋转的中心;第二个参数:旋转的角度;第三个参数:缩放的系数 ②程序
import cv2 import numpy as np img = cv2.imread("E:\\pictures\\4.jpg",1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] #定义旋转矩阵 matRotate = cv2.getRotationMatrix2D((height*0.5,width*0.5),45,0.5) dst = cv2.warpAffine(img,matRotate,(height,width)) cv2.imshow('dst',dst) cv2.waitKey(0)方法三:所谓灰度图,即RBG三通道的值一样,R=G=B = gray
import cv2 import numpy as np img = cv2.imread("E:\\pictures\\4.jpg",1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] # RGB R=G=B = gray (R+G+G)/3 dst = np.zeros((height,width,3),np.uint8) for i in range(0,height): #行 for j in range(0,width): #列 (b,g,r) = img[i,j] #表示原图每个像素的三通道的值 gray = (int(b) + int(g) +int(r))/3 dst[i,j] = np.uint8(gray) cv2.imshow('dst',dst) cv2.waitKey(0)方法四:公式:gray = r0.299 + g0.587 +b*0.114 前面的程序与上面相同,就for循环这里改变
for i in range(0,height): #行 for j in range(0,width): #列 (b,g,r) = img[i,j] #表示原图每个像素的三通道的值 b = int(b) g = int(g) r = int(r) gray = r*0.299+g*0.587+b*0.114 dst[i,j] = np.uint8(gray)对于方法四中的公式法,浮点数转为整型的过程中,会存在丢失精度的可能,可以将原值进行放大的操作,如乘1000等等
①灰度图像的颜色反转 0-255 255-当前
import cv2 import numpy as np img = cv2.imread("E:\\pictures\\4.jpg",1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) dst = np.zeros((height,width,1),np.uint8) #转为灰度图像后是一个通道 for i in range(0,height): #行 for j in range(0,width): #列 grayPixel = gray[i,j] dst[i,j] = 255-grayPixel cv2.imshow('dst',dst) cv2.waitKey(0)②彩色图像的颜色反转 RGB 255-R=newR:0-255 255-当前
import cv2 import numpy as np img = cv2.imread("E:\\pictures\\4.jpg",1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] dst = np.zeros((height,width,3),np.uint8) #彩色图像有3个通道 for i in range(0,height): #行 for j in range(0,width): #列 (b,g,r) = img[i,j] dst[i,j] = (255-b,255-g,255-r) #对三个通道进行赋值 cv2.imshow('dst',dst) cv2.waitKey(0)原理:马赛克是有形状的,有圆形、矩形等等,本节讲的是矩形。工作原理:首先选取马赛克的范围,然后再选取一个小区域,将这区域中的所有像素值,选用其中某一个点的像素值来表示。
import cv2 import numpy as np img = cv2.imread("E:\\pictures\\4.jpg",1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] for m in range(100,300): #行 for n in range(100,200): #列 # 将10*10像素的所有值用一个像素点表示 if m%10 == 0 and n%10 == 0: for i in range(0,10): for j in range(0,10): (b,g,r) = img[m,n] img[i+m,j+n] = (b,g,r) cv2.imshow('dst',img) cv2.waitKey(0)输出:
理解:毛玻璃操作与马赛克的区别:马赛克是选取一个区域,其中该区域的像素值是由某指定的点的像素值,而毛玻璃中该区域的像素值是该区域中随机一个点的像素值。
import cv2 import numpy as np import random img = cv2.imread("E:\\pictures\\4.jpg",1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] dst = np.zeros((height,width,3),np.uint8) mm = 8 for m in range(0,height-mm): #行-mm,防止溢出 for n in range(0,width-mm): #列-mm index = int(random.random()*8) #产生随机数0-7 (b,g,r) = img[m+index,n+index] dst[m,n] = (b,g,r) cv2.imshow('dst',dst) cv2.waitKey(0)输出: PS:可以发现效果图中,图片的右边与下边有黑边,这是因为在for循环中,为了防止溢出,height和width都减去了mm即8个像素的值,一开始dst是设置的黑色。
方法:将图片1乘以一个权重 + 图片2乘以一个权重,每个像素值都这样,要保证两图片大小一致。
import cv2 import numpy as np img0 = cv2.imread("E:\\pictures\\34.jpg",1) img1 = cv2.imread("E:\\pictures\\35.jpg",1) imgInfo = img0.shape height = imgInfo[0] width = imgInfo[1] #定义要融合的部分ROI,这里只融合图片的四分之一 roiH = int(height/2) roiW = int(width/2) img0ROI = img0[0:roiH,0:roiW] img1ROI = img1[0:roiH,0:roiW] #dst dst = np.zeros((roiH,roiW,3),np.uint8) dst = cv2.addWeighted(img0ROI,0.5,img1ROI,0.5,0) #0.5表示权重 cv2.imshow('dst',dst) cv2.waitKey(0)边缘检测的实质是卷积运算 canny算子的步骤:1.转化为灰度图像 2.采用高斯滤波 3.调用canny方法
import cv2 img = cv2.imread("E:\\pictures\\4.jpg",1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] cv2.imshow('src',img) gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) imgG = cv2.GaussianBlur(gray,(3,3),0) #(3,3)表示内核的大小 dst = cv2.Canny(img,50,50) #如果图片经过卷积后大于50这个值,就认为是边缘 cv2.imshow('dst',dst) cv2.waitKey(0)输出:
Sobel算子:步骤 ①算子模板:分为竖直方向的算子和水平方向的算子 Eg.[ 1 2 1 [ 1 0 -1 0 0 0 2 0 -2 -1 -2 -1] 为竖直方向的算子 1 0 -1] 为水平方向的算子 ②图片卷积 举个公式:[ 1 2 3 4 ] [ a b c d ] a1+b2+c3+d4 = dst ③阈值判断 Sqrt( aa + bb) 若大于阈值,则为边缘,小于则不是。 a指的是竖直方向的算子和竖直方向的图片进行卷积后得到的就是a,叫梯度,同理b是水平方向的梯度
# 用源码编写的情况 import cv2 import numpy as np import math img = cv2.imread("E:\\pictures\\4.jpg",1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] cv2.imshow('src',img) gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) dst = np.zeros((height,width,1),np.uint8) for i in range(0,height-2): for j in range(0,width-2): #这里减2的原因是:算子模板是3*3的,右下角像素的坐标为2,2,防止溢出 #下面的计算就是用的上面举例的算子模板 gy = gray[i,j]*1+gray[i,j+1]*2+gray[i,j+2]*1-\ gray[i+2,j]*1-gray[i+2,j+1]*2-gray[i+2,j+2]*1 #采用竖直方向的算子,横着计算 gx = gray[i,j]*1+gray[i+1,j]*2+gray[i+2,j]*1-\ gray[i,j+2]*1-gray[i+1,j+2]*2-gray[i+2,j+2]*1 #采用水平方向的算子,竖着计算 grad = math.sqrt(gx*gx+gy*gy) if grad >50: dst[i,j] = 255 #是边界,设为白色 else: dst[i,j] = 0 #不是边界,设为黑色,和背景相同 cv2.imshow('dst',dst) cv2.waitKey(0)输出:
浮雕和边缘检测比较类似,也是计算梯度的过程 公式为:newP = gray0 - gray1 + 150 (两个灰度值相减,凸出对比,加150增强浮雕的效果)
import cv2 import numpy as np img = cv2.imread("E:\\pictures\\4.jpg",1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] cv2.imshow('src',img) gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # newP = gray0 - gray1 + 150 dst = np.zeros((height,width,1),np.uint8) for i in range(0,height): for j in range(0,width-1): grayP0 = int(gray[i,j]) #获取当前像素的灰度值 grayP1 = int(gray[i,j+1]) #获取下一个像素的灰度值 newP = grayP0-grayP1 + 150 if newP > 255: newP = 255 if newP < 0: newP = 0 dst[i,j] = newP cv2.imshow('dst',dst) cv2.waitKey(0)输出:
原理:将原图像的RGB像素值,映射到你自己认为的一个颜色区间
import cv2 import numpy as np img = cv2.imread("E:\\pictures\\4.jpg",1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] cv2.imshow('src',img) gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # RGB 产生蓝色的效果 b=b*1.5 g=g*1.3 dst = np.zeros((height,width,3),np.uint8) for i in range(0,height): for j in range(0,width): (b,g,r) = img[i,j] b = b*1.5 g = g*1.3 if b > 255: b = 255 if g > 255: g = 255 dst[i,j] = (b,g,r) cv2.imshow('dst',dst) cv2.waitKey(0)输出:
步骤:1.彩色图像到灰度图像的转换 2.分成若干个区域,比如77或者88区域,统计每个区域中的灰度值 3.将0-255划分为几个等级,并把第二步中的灰度值映射到这个等级中 4.统计之前划分区域映射到第三步等级中的个数 5.用统计出来的平均值替换原图像的像素值
import cv2 import numpy as np img = cv2.imread("E:\\pictures\\4.jpg",1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] cv2.imshow('src',img) gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) dst = np.zeros((height,width,3),np.uint8) for i in range(4,height-4): for j in range(4,width-4): array1 = np.zeros(8,np.uint8) #定义8个灰度等级 for m in range(-4,4): #选取8*8的区域 for n in range(-4,4): #步骤三:灰度等级的统计 p1 = int(gray[i+m,j+n]/32) #p1范围是0-7 array1[p1] = array1[p1] + 1 #表示当前的像素值,完成累加 currentMax = array1[0] #获取array1中哪个段内的像素值最多 l = 0 for k in range(0,8): if currentMax < array1[k]: currentMax = array1[k] l = k #统计均值 for m in range(-4,4): for n in range(-4,4): if gray[i+m,j+n] >=(l*32) and gray[i+m,j+n]<=((l+1)*32): (b,g,r) = img[i+m,j+n] dst[i,j] = (b,g,r) cv2.imshow('dst',dst) cv2.waitKey(0)参数说明:1.线段绘制的目标图像 2.线段绘制的起始点 3.线段绘制的结束点 4.线段的颜色 5.线段的宽度 6.线段的类型LINE_AA为抗锯齿形。
①绘制矩形
cv2.rectangle(dst,(50,100),(200,300),(0,0,255),-1)参数说明:1.矩形绘制的目标图像 2.矩形的左上角坐标 3.矩形的右下角坐标 4.矩形线条的颜色 5.是否填充,若为-1,表示填充;若为大于0的数,表示线段的宽度 ②绘制圆形
cv2.circle(dst,(50,50),50,(0,0,255),2)参数说明:1.圆形绘制的目标图像 2.圆心的坐标 3.圆的半径 4圆形线条的颜色 5.是否填充,若为-1,表示填充;若为大于0的数,表示线段的宽度 ③绘制椭圆
cv2.ellipse(dst,(100,100),(150,100),0,0,180,(0,0,255),-1)参数说明:1.椭圆绘制的目标图像 2.椭圆的中心点坐标 3.椭圆的长轴和短轴的长度 4.椭圆的角度 5.起始角度 6.结束角度 7.椭圆的颜色 8.是否填充 ④绘制任意多边形
points = [] #表示多边形的各个顶点坐标 cv2.polylines(dst,[points],True,(0,0,255))输出:
import cv2 img = cv2.imread("E:\\pictures\\image0.jpg",1) height = int(img.shape[0]*0.2) width = int(img.shape[1]*0.2) imgResize = cv2.resize(img,(width,height)) #将要加上的图片缩放处理 for i in range(0,height): for j in range(0,width): img[i+200,j+350] = imgResize[i,j] cv2.imshow('dst',img) cv2.waitKey(0)输出:
API:calcHist() 绘制图像的直方图
import cv2 import numpy as np def ImageHist(image,type): #定义个绘制直方图的函数 color = (255,255,255) #设置颜色 windowName = 'Gray' if type == 31: color = (255,0,0) windowName = 'Blue Hist' elif type == 32: color = (0,255,0) windowName = 'Green Hist' elif type == 33: color = (0,0,255) windowName = 'Red Hist' hist = cv2.calcHist([image],[0],None,[256],[0.0,255.0]) #直方图函数参数说明:1.图片 2.当前通道 3.掩膜 4.直方图的大小,分成多少类 # 5.表明直方图中各个像素的值0-255表明像素从0-255都遍历一次 #开始绘图 #首先要知道直方图中最大值最小值以及它们的坐标,为了下面的坐标归一化 minValue,maxValue,minIndex,maxIndex = cv2.minMaxLoc(hist) histImage = np.zeros([256,256,3],np.uint8) for h in range(256): intenNormal = int(hist[h]*256/maxValue) #将值归一化,使绘图美观 cv2.line(histImage,(h,256),(h,256-intenNormal),color) cv2.imshow(windowName,histImage) return histImage img = cv2.imread('E:\\pictures\\image0.jpg') channels = cv2.split(img) #将RGB图像分割成R G B 三个通道 for i in range(0,3): ImageHist(channels[i],31+i) cv2.waitKey(0)输出:
API:equalizeHist 直方图的均衡化 merge 图像通道的合成 split 图像通道的分解 ①灰度图像的直方图均衡化
import cv2 img = cv2.imread('E:\\pictures\\image0.jpg',1) gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) cv2.imshow('src',gray) dst = cv2.equalizeHist(gray) cv2.imshow('dst',dst) cv2.waitKey(0)输出: ②彩色图像的直方图均衡化
import cv2 img = cv2.imread('E:\\pictures\\image0.jpg',1) (b,g,r) = cv2.split(img) #通道分解 bH = cv2.equalizeHist(b) gH = cv2.equalizeHist(g) rH = cv2.equalizeHist(r) result = cv2.merge((bH,gH,rH)) #通道合成 cv2.imshow('src',img) cv2.imshow('dst',result) cv2.waitKey(0)输出: ③YUV图像的直方图均衡化
import cv2 img = cv2.imread('E:\\pictures\\image0.jpg',1) imgYUV = cv2.cvtColor(img,cv2.COLOR_BGR2YCrCb) channelYUV = cv2.split(imgYUV) channelYUV[0] = cv2.equalizeHist(channelYUV[0]) channels = cv2.merge(channelYUV) result = cv2.cvtColor(channels,cv2.COLOR_BGR2YCrCb) cv2.imshow('src',imgYUV) cv2.imshow('dst',result) cv2.waitKey(0)输出:
API:inpaint 图片修补 步骤:1.需要一个损坏的图 2.知道损坏的像素坐标 3.调用API
输出:
①累计概率的概念:假设直方图灰度等级1出现的概率是0.2,2出现的概率是0.3,3出现的概率是0.1,则1的累计概率是0.2,2的累计概率是0.2+0.3=0.5,3的累计概率是0.2+0.3+0.1=0.6。 假设256个灰度等级中,100的累计概率为0.5,则255*0.5=new的值作为映射的新的值
import cv2 import numpy as np img = cv2.imread('E:\\pictures\\image0.jpg',1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) cv2.imshow('src',gray) count = np.zeros(256,np.float) #表示每个像素值在每个灰度等级下出现的概率,256个等级 for i in range(0,height): for j in range(0,width): pixel = gray[i,j] #获取每个灰度等级的像素 index = int(pixel) #转为int类型 count[index] = count[index]+1 for i in range(0,255): #每个灰度等级出现的概率 #分子是count,分母是所有的像素 count[i] = count[i]/(height*width) #计算累计概率 sum1 = float(0) for i in range(0,256): sum1 = sum1 + count[i] count[i] = sum1 #计算映射表 map1 = np.zeros(256,np.uint16) for i in range(0,256): map1[i] = np.uint16(count[i]*255) #映射 for i in range(0,height): for j in range(0,width): pixel = gray[i,j] gray[i,j] = map1[pixel] cv2.imshow('dst',gray) cv2.waitKey(0)输出:
PS:和上节的代码差不多,灰度图是一个通道,彩色图是三个通道
import cv2 import numpy as np img = cv2.imread('E:\\pictures\\image0.jpg',1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] cv2.imshow('src',img) count_b = np.zeros(256,np.float) count_g = np.zeros(256,np.float) count_r = np.zeros(256,np.float) for i in range(0,height): for j in range(0,width): (b,g,r) = img[i,j] index_b = int(b) index_g = int(g) index_r = int(r) count_b[index_b] = count_b[index_b]+1 count_g[index_g] = count_g[index_g] + 1 count_r[index_r] = count_r[index_r] + 1 for i in range(0,255): #分子是count,分母是所有的像素 count_b[i] = count_b[i]/(height*width) count_g[i] = count_g[i] / (height * width) count_r[i] = count_r[i] / (height * width) #计算累计概率 sum_b = float(0) sum_g = float(0) sum_r = float(0) for i in range(0,256): sum_b = sum_b + count_b[i] sum_g = sum_g + count_g[i] sum_r = sum_r + count_r[i] count_b[i] = sum_b count_g[i] = sum_g count_r[i] = sum_r #计算映射表 map_b = np.zeros(256,np.uint16) map_g = np.zeros(256,np.uint16) map_r = np.zeros(256,np.uint16) for i in range(0,256): map_b[i] = np.uint16(count_b[i]*255) map_g[i] = np.uint16(count_b[i] * 255) map_r[i] = np.uint16(count_b[i] * 255) #映射 dst = np.zeros((height,width,3),np.uint8) for i in range(0,height): for j in range(0,width): (b,g,r) = img[i,j] b = map_b[b] g = map_b[g] r = map_b[r] dst[i,j] = (b,g,r) cv2.imshow('dst',dst) cv2.waitKey(0)输出:
原理:将每个像素点三通道的像素值增加,即p = p + 40
import cv2 import numpy as np img = cv2.imread('E:\\pictures\\image0.jpg',1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] cv2.imshow('src',img) dst = np.zeros((height,width,3),np.uint8) for i in range(0,height): for j in range(0,width): (b,g,r) = img[i,j] bb = int(b)+40 gg = int(g)+40 rr = int(r)+40 if bb>255: bb = 255 if gg>255: gg = 255 if rr>255: rr = 255 dst[i,j] = (bb,gg,rr) cv2.imshow('dst',dst) cv2.waitKey(0)输出:
API:bilateralFilter 双边滤波
import cv2 img = cv2.imread('E:\\pictures\\image1.png',1) dst = cv2.bilateralFilter(img,15,35,35) cv2.imshow('src',img) cv2.imshow('dst',dst) cv2.waitKey(0)输出:
API:GaussianBlur 高斯均值滤波
#调用API import cv2 img = cv2.imread('E:\\pictures\\image0.JPG',1) cv2.imshow('src',img) dst = cv2.GaussianBlur(img,(5,5),1.5) cv2.imshow('dst',dst) cv2.waitKey(0) # 源码分析 import cv2 import numpy as np img = cv2.imread('E:\\pictures\\image0.JPG', 1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] dst = np.zeros((height,width,3),np.uint8) for i in range(3,height-3): for j in range(3,width-3): sum_b = int(0) sum_g = int(0) sum_r = int(0) for m in range(-3,3):#-3 -2 -1 0 1 2 for n in range(-3,3): (b,g,r) = img[i+m,j+n] sum_b = sum_b+int(b) sum_g = sum_g+int(g) sum_r = sum_r+int(r) b = np.uint8(sum_b/36) g = np.uint8(sum_g/36) r = np.uint8(sum_r/36) dst[i,j] = (b,g,r) cv2.imshow('dst',dst) cv2.waitKey(0)