Opencv及常用方法示例程式碼
包括一些Opencv的基本示例程式碼,方便以後查閱。
一
1.1在Pycharm中執行tensorflow出現的問題
解決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))
1.2案例1:圖片的讀取和展示
import cv2
srcImage = cv2.imread("E:\\pictures\\12.jpg",1)
cv2.imshow("srcImage",srcImage)
cv2.waitKey(0)
# PS:在Python中圖片的名稱、輸出視窗等都不能有中文,這點和C++不同
1.3案例2:圖片寫入
import cv2
srcImage = cv2.imread("E:\\pictures\\12.jpg",1)
cv2.imwrite("srcImage.jpg",srcImage)#第一個引數是影像名,第二個引數是圖片的資料
1.4案例3:不同圖片質量儲存
①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是最低的壓縮比,影像效果最好
1.5畫素操作基礎
①對於RGB影像
eg.一個影像1.14M = 7205473*8 bit/8 (B)
含義:寬×高×三個畫素通道×每個顏色變數是八位的 / 8(轉化為位元組要除8)
②對於PNG影像
除了RGB三個通道,還要加上透明度alpha 通道
1.6案例4:畫素讀取寫入
import cv2
srcImage = cv2.imread("E:\\pictures\\12.jpg",1)
#畫素的讀取
(b,g,r) = srcImage[400,400]
#Opencv中的畫素排布是BGR的格式 [400,400]表示該座標的畫素值
print("b="+str(b)+",g="+str(g)+",r="+str(r))
#畫素的寫入,畫出一條第10行第100至第110行第110列的直線
#10 100 ----- 110 100
for i in range(1,100):
srcImage[10+i,100] = (255,0,0)
cv2.imshow("srcImage",srcImage)
cv2.waitKey(0)
1.8tensorflow常量變數定義
import tensorflow as tf
data1 = tf.constant(2.5) #定義常量
data2 = tf.constant(2,dtype=tf.int32)
data3 = tf.Variable(10,name='var') #定義變數
print(data1)
print(data3) #直接輸出的是資料的資訊
#列印常量
sess = tf.Session()
print(sess.run(data1))
print(sess.run(data2))
#列印變數
init = tf.global_variables_initializer()
sess.run(init)
print(sess.run(data3))
# 輸出:
# Tensor("Const:0", shape=(), dtype=float32)
# <tf.Variable 'var:0' shape=() dtype=int32_ref>
# 2.5
# 2
# 10
1.9tensorflow運算原理
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))
1.10常量變數四則運算
①常量的四則運算
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!')
1.11矩陣基礎1
①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]
1.12矩陣基礎2
注意矩陣乘法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]])]
1.13矩陣基礎3
①特殊矩陣的初始化
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區間隨機取
1.14numpy模組使用
import numpy as np
data1 = np.array([1,2,3,4,5])
print(data1)
data2 = np.array(([1,2],[3,4]))
print(data2)
print(data1.shape,data2.shape) #列印矩陣的維度
print(np.zeros([2,3]),np.ones([2,2])) #zeros和ones
data2[1,0] = 5 #將data2矩陣中第二行第一列的元素賦值為5
print(data2)
#矩陣的基本運算
data3 = np.ones([2,3])
print(data3*2) #對應元素相乘
print(data3/3) #對應元素相除
print(data3+2) #對應元素相加
#矩陣+ *
data4 = np.array([[1,2,3],[4,5,6]])
print(data3+data4)
print(data3*data4)
1.15matplotlib模組的使用
import numpy as np
import matplotlib.pyplot as plt
x = np.array([1,2,3,4,5,6,7,8])
y = np.array([3,5,7,6,2,6,10,15])
plt.plot(x,y,'red') #繪製折線,引數:x軸,y軸,顏色
plt.plot(x,y,'g',lw=10) #'g'表示綠色,lw是折現的寬度
#三種影像:折線,餅狀,柱狀
x = np.array([1,2,3,4,5,6,7,8])
y = np.array([3,5,7,6,2,6,10,15])
plt.bar(x,y,0.5,alpha=1,color='b')
#0.5表示柱狀的寬度,alpha表示透明度,color表示顏色
plt.show()
輸出:
二
2.1圖片縮放1
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)
輸出格式:高度(行)、寬度(列)、通道數
2.2圖片縮放2
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%
2.3圖片縮放3
前面已經掌握了演算法的原理和圖片縮放得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)
2.4圖片剪下
舉例:剪下影像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)
2.5圖片位移
①示例程式
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)
2.6圖片映象
①步驟:①建立一個足夠大的“畫板”②將一副影像分別從前向後、從後向前繪製③繪製中心分割線
②程式
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)
2.7圖片縮放
參考圖片位移
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)
2.8圖片仿射變換
import cv2
import numpy as np
img = cv2.imread("E:\\pictures\\4.jpg",1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
#已知原圖上的三個點(左上角,左下角,右上角)
matSrc = np.float32([[0,0],[0,height-1],[width-1,0]])
#將這三個點對映到目標影像上
matDst = np.float32([[50,50],[300,height-200],[width-300,100]])
#組合兩個矩陣
matAffine = cv2.getAffineTransform(matSrc,matDst)
dst = cv2.warpAffine(img,matAffine,(width,height))
cv2.imshow('dst',dst)
cv2.waitKey(0)
輸出:
2.9圖片旋轉
①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)
三
3.1影像灰度處理1
# 方法一:一開始圖片匯入的時候就以灰度影像顯示
img0 = cv2.imread('image0.jpg',0)
# 方法二:使用cvtColor,將彩色圖轉為灰度圖
dst = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #顏色空間轉換
3.2影像灰度處理2
方法三:所謂灰度圖,即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等等
3.3顏色反轉
①灰度影像的顏色反轉 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)
3.4馬賽克
原理:馬賽克是有形狀的,有圓形、矩形等等,本節講的是矩形。工作原理:首先選取馬賽克的範圍,然後再選取一個小區域,將這區域中的所有畫素值,選用其中某一個點的畫素值來表示。
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)
輸出:
3.5毛玻璃
理解:毛玻璃操作與馬賽克的區別:馬賽克是選取一個區域,其中該區域的畫素值是由某指定的點的畫素值,而毛玻璃中該區域的畫素值是該區域中隨機一個點的畫素值。
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是設定的黑色。
3.6圖片融合
方法:將圖片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)
3.7邊緣檢測1
邊緣檢測的實質是卷積運算
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)
輸出:
3.8邊緣檢測2
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)
輸出:
3.9浮雕效果
浮雕和邊緣檢測比較類似,也是計算梯度的過程
公式為: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)
輸出:
3.10顏色對映
原理:將原影像的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)
輸出:
3.11油畫特效
步驟: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)
3.12線段繪製
cv2.line(dst,(100,100),(300,300),(0,0,255),20,cv2.LINE_AA)
引數說明:1.線段繪製的目標影像 2.線段繪製的起始點 3.線段繪製的結束點 4.線段的顏色 5.線段的寬度 6.線段的型別LINE_AA為抗鋸齒形。
3.13矩形圓形任意多邊形繪製
①繪製矩形
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))
3.14文字圖片繪製
import cv2
img = cv2.imread("E:\\pictures\\image0.jpg",1)
font = cv2.FONT_HERSHEY_SIMPLEX #字型的選擇
cv2.rectangle(img,(200,100),(500,400),(0,255,0),3)
cv2.putText(img,'this is a flower',(100,300),font,1,(200,100,255),2,cv2.LINE_AA)
#引數:1.dst 2.文字內容 3.座標 4.字型 5.字型大小 6.字型顏色 7.字型粗細 8.線條線型
cv2.imshow('dst',img)
cv2.waitKey(0)
輸出:
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)
輸出:
四
4.1彩色圖片直方圖
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)
輸出:
4.2直方圖均衡化
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)
輸出:
4.3圖片修補
API:inpaint 圖片修補
步驟:1.需要一個損壞的圖 2.知道損壞的畫素座標 3.呼叫API
4.4灰度直方圖原始碼
# 本質:統計每個畫素灰度 出現的概率 0-255
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('E:\\pictures\\image0.jpg',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
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)
x = np.linspace(0,255,256)
y = count
plt.bar(x,y,0.9,alpha=1,color='b')
plt.show()
cv2.waitKey(0)
輸出:
4.5彩色直方圖原始碼
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('E:\\pictures\\image0.jpg',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
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,256):
count_b[i] = count_b[i]/(height*width)
count_g[i] = count_g[i]/(height*width)
count_r[i] = count_r[i]/(height*width)
x = np.linspace(0,255,256)
y1 = count_b
plt.figure()
plt.bar(x,y1,0.9,alpha=1,color='b')
y2 = count_g
plt.figure()
plt.bar(x,y2,0.9,alpha=1,color='g')
y3 = count_r
plt.figure()
plt.bar(x,y3,0.9,alpha=1,color='r')
plt.show()
cv2.waitKey(0)
3.15灰度直方圖均衡化原始碼分析
①累計概率的概念:假設直方圖灰度等級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)
輸出:
3.16彩色影像直方圖均衡化原始碼分析
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)
輸出:
3.17亮度增強
原理:將每個畫素點三通道的畫素值增加,即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)
輸出:
3.18磨皮美白
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)
輸出:
3.19高斯均值濾波
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)
3.20中值濾波
#原始碼分析
import cv2
import numpy as np
img = cv2.imread('image11.jpg',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
img = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
cv2.imshow('src',img)
dst = np.zeros((height,width,3),np.uint8)
collect = np.zeros(9,np.uint8)
for i in range(1,height-1):
for j in range(1,width-1):
k = 0
for m in range(-1,2):
for n in range(-1,2):
gray = img[i+m,j+n]
collect[k] = gray
k = k+1
# 0 1 2 3 4 5 6 7 8
# 1
for k in range(0,9):
p1 = collect[k]
for t in range(k+1,9):
if p1<collect[t]:
mid = collect[t]
collect[t] = p1
p1 = mid
dst[i,j] = collect[4]
cv2.imshow('dst',dst)
cv2.waitKey(0)
相關文章
- MySql連線資料庫常用引數及程式碼示例MySql資料庫
- 常用設計模式之.Net示例程式碼合集設計模式
- opencv + SVM 程式碼OpenCV
- curl常用引數詳解及示例
- 主題:人臉檢測原理及示例(OpenCV+Python)OpenCVPython
- 排序程式碼示例排序
- RabbitMQ 程式碼示例MQ
- JavaScript 陣列方法集合及示例!JavaScript陣列
- 正則匹配方法及示例
- Mac搭建appium環境及python執行程式碼示例MacAPPPython行程
- 常見的PID的演算法及程式碼示例演算法
- 常用網路命令 dig 詳解及使用示例
- JavaScript中常用的事件程式碼及例項JavaScript事件
- Java NIO 程式碼示例Java
- java SPI 程式碼示例Java
- Java的六種執行緒狀態及程式碼示例Java執行緒
- iOS逆向——Method Swizzle及WeChat註冊、登入程式碼示例iOS
- 三方登入原理及後端示例程式碼後端
- Python | Python常用函式、方法示例總結(API)Python函式API
- LinkedList 基本示例及原始碼解析原始碼
- Redis | Redis常用命令及示例總結(API)RedisAPI
- 小程式 · 常用方法
- 乾貨丨Python介面測試自動化實戰及程式碼示例:含get、post等方法Python
- 常用程式碼
- 抖米多多工系統技術開發及程式碼示例
- js程式碼與html程式碼分離示例JSHTML
- Kafka 1.0.0 d程式碼示例Kafka
- 靜態代理程式碼示例
- 阿童木(ATOM)質押挖礦系統程式設計開發及程式碼示例程式設計
- 【OpenCV教程】OpenCV中對矩陣的常用操作OpenCV矩陣
- 視窗程式框架示例程式碼框架
- JSP資料互動實現過程解析及示例程式碼JS
- TreeMap原理實現及常用方法
- 【C++】【OpenCV-4.9.0】影片寫入(VideoWriter,藉助samples中的程式碼示例來進行學習)C++OpenCVIDE
- laravel常用程式碼庫:Carbon日期及時間處理包-年月日操作完整版常用方法以及使用場景Laravel
- RxJava常用操作符官方文件翻譯及Kotlin示例(1)RxJavaKotlin
- RSA加密解密示例程式碼加密解密
- pytorch程式碼示例筆記 -- AutogradPyTorch筆記