文章目錄
- 1.灰度處理
- 2.顏色反轉
- 3.馬賽克
- 4.毛玻璃效果
- 5.影像融合
- 7.邊緣檢測
1.灰度處理
1.將cv2.imread()方法的第二引數設為0即可得到灰色影像
import cv2
import numpy as np
img0 = cv2.imread('img.jpg', 0)
img1 = cv2.imread('img.jpg', 1)
print(img0.shape)
print(img1.shape)
cv2.imshow('img0', img0)
cv2.waitKey(0)
(270, 360)
(270, 360, 3)

2.通過cv2.cvtColor方法對影像進行灰度轉換
cv2.cvtColor(src, code, dst, dstCN):
-src: 目標影像
-code: 顏色轉換方式
-dst: 影像大小
-dstCN: 顏色通道大小
import cv2
import numpy as np
img = cv2.imread('img.jpg', 1)
dat = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY )
cv2.imshow('dat', dat)
cv2.waitKey(0)

原理
灰色影像的所有顏色通道的值相等,所以要想將彩色影像變為灰色影像,只需將他們顏色通道的值相等即可,
3.下面我們通過原始碼設定它們的顏色均值來使彩色影像變為灰色影像
import cv2
import numpy as np
img = cv2.imread('img.jpg', 1)
dat = np.zeros((img.shape[0], img.shape[1]), np.uint8)
for i in range(0, img.shape[0]):
for j in range(0, img.shape[1]):
(b, g, r) = img[i, j]
gray = (int(b) + int(g) +int(r)) / 3
dat[i, j] = np.uint(gray)
cv2.imshow('dat', dat)
cv2.waitKey(0)

4.通過設定 gray = r * 0.299 + g * 0.587 + b * 0.114 來變為灰色影像
import cv2
import numpy as np
img = cv2.imread('img.jpg', 1)
dat = np.zeros((img.shape[0], img.shape[1]), np.uint8)
for i in range(0, img.shape[0]):
for j in range(0, img.shape[1]):
(b, g, r) = img[i, j]
gray = int(b) * 0.114 + int(g) * 0.587 +int(r) * 0.299
dat[i, j] = np.uint(gray)
cv2.imshow('dat', dat)
cv2.waitKey(0)

2.顏色反轉
將影像的顏色反轉也就是讓255減去當前的顏色值
下面我們來實作灰色影像的顏色反轉:
import cv2
import numpy as np
img = cv2.imread('img.jpg', 1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
dat = np.zeros((img.shape[0], img.shape[1]), np.uint8)
for i in range(gray.shape[0]):
for j in range(gray.shape[1]):
dat[i, j] = 255 - gray[i, j]
cv2.imshow('dat', dat)
cv2.waitKey(0)

彩色影像的顏色反轉也是一樣的道理:
import cv2
import numpy as np
img = cv2.imread('img.jpg', 1)
dat = np.zeros((img.shape[0], img.shape[1], img.shape[2]), np.uint8)
for i in range(img.shape[0]):
for j in range(img.shape[1]):
(b, g, r) = img[i, j]
dat[i, j] = (255 - b, 255 - g, 255 - r)
cv2.imshow('src', img)
cv2.imshow('dat', dat)
cv2.waitKey(0)


3.馬賽克
原理: 取一個指定大小的視窗,將該視窗填充為一個顏色
下面我們將視窗設定為10*10來生成一個馬賽克影像
import cv2
import numpy as np
img = cv2.imread('img.jpg', 1)
height = img.shape[0]
width = img.shape[1]
for m in range(50, 150):
for n in range(100, 200):
if m % 10 == 0 and n % 10 == 0:
for i in range(10):
for j in range(10):
(b, g,r) = img[m, n]
img[m + i, n + j] = (b, g, r)
cv2.imshow('img', img)
cv2.waitKey(0)

4.毛玻璃效果
原理: 將當前的像素顏色隨機設定為視窗中的一個顏色
這里我們設定視窗為8*8來生成一個毛玻璃影像
import cv2
import random
import numpy as np
img = cv2.imread('img.jpg', 1)
height = img.shape[0]
width = img.shape[1]
dat = np.zeros(img.shape, np.uint8)
for m in range(height - 8):
for n in range(width - 8):
index = int(random.random() * 8)
(b, g, r) = img[m + index, n + index]
dat[m, n] = (b, g, r)
cv2.imshow('dat', dat)
cv2.waitKey(0)

5.影像融合
圖片乘以比例系數相加得到倆張圖片的融合效果:
target = src1 * a +src2 * (1 - a)
cv2.addWeighted(src1, alpha, src2, beta, gamma):
-src1: 第一張影像
-alpha: 第一張影像的權重
-src2: 第二張影像
-beta: 第二張影像的權重
-gamma: 要添加的標量
import cv2
import numpy as np
img1 = cv2.imread('img3.jpg', 1)
img2 = cv2.imread("img2.png", 1)
dat = np.zeros(img1.shape, np.uint8)
dat = cv2.addWeighted(img1, 0.5, img2, 0.5, 0)
cv2.imshow('dat', dat)
cv2.waitKey(0)



7.邊緣檢測
canny邊緣檢測:
首先,影像降噪,我們知道梯度算子可以用于增強影像,本質上是通過增強邊緣輪廓來實作的,也就是說是可以檢測到邊緣的,但是,它們受噪聲的影響都很大,那么,我們第一步就是想到要先去除噪聲,因為噪聲就是灰度變化很大的地方,所以容易被識別為偽邊緣,
第二步,計算影像梯度,得到可能邊緣,計算影像梯度能夠得到影像的邊緣,因為梯度是灰度變化明顯的地方,而邊緣也是灰度變化明顯的地方,當然這一步只能得到可能的邊緣,因為灰度變化的地方可能是邊緣,也可能不是邊緣,這一步就有了所有可能是邊緣的集合,
第三步,非極大值抑制,通常灰度變化的地方都比較集中,將區域范圍內的梯度方向上,灰度變化最大的保留下來,其它的不保留,這樣可以剔除掉一大部分的點,將有多個像素寬的邊緣變成一個單像素寬的邊緣,即“胖邊緣”變成“瘦邊緣”,
第四步,雙閾值篩選,通過非極大值抑制后,仍然有很多的可能邊緣點,進一步的設定一個雙閾值,即低閾值(low),高閾值(high),灰度變化大于high的,設定為強邊緣像素,低于low的,剔除,在low和high之間的設定為弱邊緣,進一步判斷,如果其領域內有強邊緣像素,保留,如果沒有,剔除,
這樣做的目的是只保留強邊緣輪廓的話,有些邊緣可能不閉合,需要從滿足low和high之間的點進行補充,使得邊緣盡可能的閉合,
import cv2
import numpy
import random
img = cv2.imread('img.jpg', 1)
cv2.imshow('src', img)
# canny 1 gray 2 高斯 3 canny
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
imgG = cv2.GaussianBlur(gray, (3,3), 0)
dat = cv2.Canny(img, 50, 50)
cv2.imshow('dat', dat)
cv2.waitKey(0)


sobel算子:

利用Sobel算子對影像的每一個像素進行卷積運算得到影像梯度( x 方向和 y 方向),我們可以通過計算sqrt(a**2 + b**2)來得到梯度幅值(其中 a 和 b 分別為水平方向的梯度和豎直方向的梯度),判斷該值是否大于判決門限,如果大于則認為是邊緣
下面我們用原始碼來實作:
import cv2
import math
import numpy as np
import random
img = cv2.imread('img.jpg', 1)
cv2.imshow('src', img)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 轉換為灰色影像
dat = np.zeros((img.shape[0], img.shape[1], 1), np.uint8) #生成空模板
for i in range(img.shape[0] - 2):
for j in range(img.shape[1] - 2):
# 求梯度
gy = gray[i, j] + gray[i, j + 1] * 2 + gray[i,j + 2] - (gray[i + 2, j] + gray[i + 2, j + 1] * 2 + gray[i + 2, j + 2])
gx = gray[i, j] + gray[i + 1, j] * 2 + gray[i + 2, j] - (gray[i, j + 2] + gray[i + 1, j + 2] * 2 + gray[i + 2, j + 2])
#得到梯度幅值
grad = math.sqrt(gx*gx + gy*gy)
if grad > 50: # 判斷是否為邊緣
dat[i, j] = 255
else:
dat[i, j] = 0
cv2.imshow('dat', dat)
cv2.waitKey(0)


轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/173032.html
標籤:其他
