日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

python 视觉技术_python+opencv实现机器视觉基础技术(边缘提取,图像滤波,边缘检测算子,投影,车牌字符分割)...

發(fā)布時(shí)間:2025/3/19 python 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python 视觉技术_python+opencv实现机器视觉基础技术(边缘提取,图像滤波,边缘检测算子,投影,车牌字符分割)... 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

機(jī)器視覺是人工智能正在快速發(fā)展的一個(gè)分支。簡(jiǎn)單說(shuō)來(lái),機(jī)器視覺就是用機(jī)器代替人眼來(lái)做測(cè)量和判斷。它是一項(xiàng)綜合技術(shù),包括圖像處理、機(jī)械工程技術(shù)、控制、電光源照明、光學(xué)成像、傳感器、模擬與數(shù)字視頻技術(shù)、計(jì)算機(jī)軟硬件技術(shù)(圖像增強(qiáng)和分析算法、圖像卡、 I/O卡等)。

下面介紹一些機(jī)器視覺的基礎(chǔ)方法,用到的技術(shù)是python+opencv。python是一種很方便的高級(jí)編程語(yǔ)言,代碼量少,而OpenCV是一個(gè)基于BSD許可發(fā)行的跨平臺(tái)計(jì)算機(jī)視覺庫(kù),可以運(yùn)行在Linux、Windows、Android和Mac OS操作系統(tǒng)上。它輕量級(jí)而且高效——由一系列 C 函數(shù)和少量 C++ 類構(gòu)成,同時(shí)提供了Python、Ruby、MATLAB等語(yǔ)言的接口,實(shí)現(xiàn)了圖像處理和計(jì)算機(jī)視覺方面的很多通用算法。

一:邊緣提取

在機(jī)器視覺中,一個(gè)非常基礎(chǔ)的操作就是圖像處理,而在圖像處理中有一個(gè)十分重要的知識(shí)就是邊緣提取。邊緣提取,指數(shù)字圖像處理中,對(duì)于圖片輪廓的一個(gè)處理。對(duì)于邊界處,灰度值變化比較劇烈的地方,就定義為邊緣。也就是拐點(diǎn),拐點(diǎn)是指函數(shù)發(fā)生凹凸性變化的點(diǎn)。和高數(shù)的導(dǎo)數(shù)有聯(lián)系,將某個(gè)指定的物體的邊緣進(jìn)行提取出來(lái)。而用python+opencv可以很方便地進(jìn)行邊緣提取操作。

步驟如下:

1.對(duì)圖像進(jìn)行閾值分割并反色

首先需要新建一個(gè)python文件,導(dǎo)入cv2的庫(kù)(OpenCV2的python庫(kù)),并顯示一張圖片,代碼為:

import cv2

# 讀取本相對(duì)路徑下的initial.bmp文件

image = cv2.imread ("initial.bmp")

# 將image對(duì)應(yīng)圖像在圖像窗口顯示出來(lái)

cv2.imshow('initial',image)

# waitKey使窗口保持靜態(tài)直到用戶按下一個(gè)鍵

cv2.waitKey(0)

對(duì)圖像進(jìn)行閾值分割,閾值設(shè)定為80,得到二值化灰度圖,代碼為:

# 對(duì)圖像進(jìn)行閾值分割,閾值設(shè)定為80,得到二值化灰度圖

ret,image1 = cv2.threshold(image,80,255,cv2.THRESH_BINARY)

cv2.imshow('grayscale',image1)

將圖像進(jìn)行反色,代碼如下:

image2 = image1.copy()# 復(fù)制圖片

for i in range(0,image1.shape[0]):#image.shape表示圖像的尺寸和通道信息(高,寬,通道)

for j in range(0,image1.shape[1]):

image2[i,j]= 255 - image1[i,j]

cv2.imshow('colorReverse',image2)

2.邊緣提取

下面就是邊緣提取了,用findContours差影法或者Canny方法檢測(cè)邊緣,用原圖像減去腐蝕后的收縮圖像,提取邊緣。代碼如下:

# 邊緣提取

img = cv2.cvtColor(image2,cv2.COLOR_BGR2GRAY)

canny_img_one = cv2.Canny(img,300,150)

canny_img_two = canny_img_one.copy()# 復(fù)制圖片

for i in range(0,canny_img_one.shape[0]):#image.shape表示圖像的尺寸和通道信息(高,寬,通道)

for j in range(0,canny_img_one.shape[1]):

canny_img_two[i,j]= 255 - canny_img_one[i,j]

cv2.imshow('edge',canny_img_two)

最終我們就可以得到一個(gè)邊緣提取后的圖形,如下:

二:圖像濾波

圖像濾波,即在盡量保留圖像細(xì)節(jié)特征的條件下對(duì)目標(biāo)圖像的噪聲進(jìn)行抑制,是圖像預(yù)處理中不可缺少的操作,其處理效果的好壞將直接影響到后續(xù)圖像處理和分析的有效性和可靠性。

噪聲就是由于成像系統(tǒng)、傳輸介質(zhì)和記錄設(shè)備等的不完善,數(shù)字圖像在其形成、傳輸記錄過(guò)程中或者在圖像處理的某些環(huán)節(jié)當(dāng)輸入的像對(duì)象并不如預(yù)想時(shí)受到的污染。

而圖像濾波有很多種濾波方式,本次實(shí)驗(yàn)采用的濾波方式是均值濾波,中值濾波和高斯濾波,以及高斯邊緣檢測(cè)。

均值濾波是典型的線性濾波算法,它是指在圖像上對(duì)目標(biāo)像素給一個(gè)模板,該模板包括了其周圍的臨近像素(以目標(biāo)像素為中心的周圍8個(gè)像素,構(gòu)成一個(gè)濾波模板,即去掉目標(biāo)像素本身),再用模板中的全體像素的平均值來(lái)代替原來(lái)像素值。

中值濾波是基于排序統(tǒng)計(jì)理論的一種能有效抑制噪聲的非線性信號(hào)處理技術(shù),中值濾波的基本原理是把數(shù)字圖像或數(shù)字序列中一點(diǎn)的值用該點(diǎn)的一個(gè)鄰域中各點(diǎn)值的中值代替,讓周圍的像素值接近的真實(shí)值,從而消除孤立的噪聲點(diǎn)。

高斯濾波是一種線性平滑濾波,適用于消除高斯噪聲,廣泛應(yīng)用于圖像處理的減噪過(guò)程。高斯濾波就是對(duì)整幅圖像進(jìn)行加權(quán)平均的過(guò)程,每一個(gè)像素點(diǎn)的值,都由其本身和鄰域內(nèi)的其他像素值經(jīng)過(guò)加權(quán)平均后得到。

邊緣檢測(cè)的目的是標(biāo)識(shí)數(shù)字圖像中亮度變化明顯的點(diǎn)。高斯邊緣檢測(cè)是用高斯濾波的方式進(jìn)行邊緣檢測(cè)。

步驟如下:

1.讀取原圖

首先展示原圖,代碼如下:

import cv2

import cv2 as cv

# 讀取本相對(duì)路徑下的initial.bmp文件

image = cv2.imread ("initial.png")

# 加入文本信息

cv2.putText(image,'initial',(50,50),cv2.FONT_HERSHEY_SIMPLEX,1.5,(255,0, 0),4)

# 將image對(duì)應(yīng)圖像在圖像窗口顯示出來(lái)

cv2.imshow('initial',image)

cv2.waitKey(0)

2.均值濾波

然后進(jìn)行均值濾波,代碼如下:

# 均值濾波

image2 = cv2.blur(image,(10,5))

cv2.putText(image2,'averageFiltering',(50,50),cv2.FONT_HERSHEY_SIMPLEX,1.5,(255,0, 0),4)

cv2.imshow('averageFiltering',image2)

3.中值濾波

然后進(jìn)行中值濾波,代碼如下:

image3 = cv2.medianBlur(image, 5)

cv2.putText(image3,'medianFiltering',(50,50),cv2.FONT_HERSHEY_SIMPLEX,1.5,(255,0, 0),4)

cv2.imshow('medianFiltering',image3)

4.高斯濾波

之后進(jìn)行高斯濾波,代碼如下:

# 高斯濾波

image4 = cv2.GaussianBlur(image,(5,5),0)

cv2.putText(image4,'gaussianFilter',(50,50),cv2.FONT_HERSHEY_SIMPLEX,1.5,(255,0, 0),4)

cv2.imshow('gaussianFilter',image4)

5.高斯邊緣檢測(cè)

最終進(jìn)行高斯邊緣檢測(cè),代碼如下:

# 高斯邊緣檢測(cè)

gau_matrix = np.asarray([[-2/28,-5/28,-2/28],[-5/28,28/28,-5/28],[-2/28,-5/28,-2/28]])

img = np.zeros(image.shape)

hight,width = image.shape

for i in range(1,hight-1):

for j in range(1,width-1):

img[i-1,j-1] = np.sum(image[i-1:i+2,j-1:j+2]*gau_matrix)

image5 = img.astype(np.uint8)

cv2.putText(image5,'gaussianEdgeDetection',(50,50),cv2.FONT_HERSHEY_SIMPLEX,1.5,(255,0, 0),4)

cv2.imshow('gaussianEdgeDetection',image5)

三:邊緣檢測(cè)算子

邊緣檢測(cè)是圖像處理和計(jì)算機(jī)視覺中的基本問題,邊緣檢測(cè)的目的是標(biāo)識(shí)數(shù)字圖像中亮度變化明顯的點(diǎn)。包括深度上的不連續(xù)、表面方向不連續(xù)、物質(zhì)屬性變化和場(chǎng)景照明變化等。是計(jì)算機(jī)視覺的特征提取的一個(gè)領(lǐng)域。

在實(shí)際的圖像分割中,往往只用到一階和二階導(dǎo)數(shù),雖然原理上,可以用更高階的導(dǎo)數(shù),但是因?yàn)樵肼暤挠绊?#xff0c;在純粹二階的導(dǎo)數(shù)操作中就會(huì)出現(xiàn)對(duì)噪聲的敏感現(xiàn)象,三階以上的導(dǎo)數(shù)信息往往失去了應(yīng)用價(jià)值。二階導(dǎo)數(shù)還可以說(shuō)明灰度突變的類型。在某些情況下,如灰度變化均勻的圖像,只利用一階導(dǎo)數(shù)可能找不到邊界,此時(shí)二階導(dǎo)數(shù)就能提供很有用的信息。二階導(dǎo)數(shù)對(duì)噪聲也比較敏感,解決的方法是先對(duì)圖像進(jìn)行平滑濾波,消除部分噪聲,再進(jìn)行邊緣檢測(cè)。不過(guò),利用二階導(dǎo)數(shù)信息的算法是基于過(guò)零檢測(cè)的,因此得到的邊緣點(diǎn)數(shù)比較少,有利于后繼的處理和識(shí)別工作。

計(jì)算機(jī)視覺正是模仿人類視覺的這個(gè)過(guò)程。因此在檢測(cè)物體邊緣時(shí),先對(duì)其輪廓點(diǎn)進(jìn)行粗略檢測(cè),然后通過(guò)鏈接規(guī)則把原來(lái)檢測(cè)到的輪廓點(diǎn)連接起來(lái),同時(shí)也檢測(cè)和連接遺漏的邊界點(diǎn)及去除虛假的邊界點(diǎn)。圖像的邊緣是圖像的重要特征,是計(jì)算機(jī)視覺、模式識(shí)別等的基礎(chǔ),因此邊緣檢測(cè)是圖象處理中一個(gè)重要的環(huán)節(jié)。

而在opencv中也有幾個(gè)邊緣檢測(cè)方法,一階的有Roberts Cross算子,Prewitt算子,Sobel算子,Canny算子,Krisch算子,羅盤算子;而二階的還有Marr-Hildreth,在梯度方向的二階導(dǎo)數(shù)過(guò)零點(diǎn)。

步驟如下:

1.顯示原圖

首先用下面的代碼表現(xiàn)出原圖像:

# 讀取本相對(duì)路徑下的dip_switch_02.bmp文件

src_s = cv2.imread ("dip_switch_02.bmp",0)

cv2.imshow('src_s',src_s)

2.對(duì)圖像進(jìn)行反色

對(duì)圖像進(jìn)行反色,反色是與原色疊加可以變?yōu)榘咨念伾?#xff0c;可以用白色(RGB:255,255,255)減去原來(lái)圖片的顏色,因此對(duì)于黑白圖片,我們先加載一個(gè)8位灰度圖像,每一個(gè)像素對(duì)應(yīng)的灰度值從0-255,則只需要讀取每個(gè)像素的灰度值A(chǔ),再將255-A寫入,這樣操作一遍后,圖像就會(huì)反色了。代碼如下:

src = cv.imread("dip_switch_02.bmp")

height, width, channels = src.shape

for row in range(height):

for list in range(width):

for c in range(channels):

pv = src[row, list, c]

src[row, list, c] = 255 - pv

cv.imshow("AfterDeal", src)

3.對(duì)圖像用sobel方法進(jìn)行邊緣檢測(cè)

Sobel算子是一種用于邊緣檢測(cè)的離散微分算子,它結(jié)合了高斯平滑和微分求導(dǎo)。該算子用于計(jì)算圖像明暗程度近似值。根據(jù)圖像邊緣旁邊明暗程度把該區(qū)域內(nèi)超過(guò)某個(gè)數(shù)的特定點(diǎn)記為邊緣。Sobel 算子在Prewitt算子的基礎(chǔ)上增加了權(quán)重的概念,認(rèn)為相鄰點(diǎn)的距離遠(yuǎn)近對(duì)當(dāng)前像素點(diǎn)的影響是不同的,距離越近的像素點(diǎn)對(duì)應(yīng)當(dāng)前像素的影響越大,從而實(shí)現(xiàn)圖像銳化并突出邊緣輪廓。

Sobel算子的邊緣定位更準(zhǔn)確,常用于噪聲較多,灰度漸變的圖像

Sobel算子包含兩組3x3的矩陣,分別為橫向及縱向模板,將之與圖像作平面卷積,即可分別得出橫向及縱向的亮度差分近似值。

代碼如下:

# 用sobel方法進(jìn)行邊緣檢測(cè)

x = cv2.Sobel(src,cv2.CV_16S,1,0)

y = cv2.Sobel(src,cv2.CV_16S,0,1)

absX = cv2.convertScaleAbs(x) # 轉(zhuǎn)回uint8

# cv2.imshow("absX", absX)

# 截圖后反轉(zhuǎn)

def inverse_color(image):

height, width, channels = image.shape

for row in range(height):

for list in range(width):

for c in range(channels):

pv = image[row, list, c]

image[row, list, c] = 255 - pv

cv.imshow("result", image)

one = cv.imread("2.jpg")

inverse_color(one)

4.對(duì)圖像用robert方法進(jìn)行邊緣檢測(cè)

Roberts 算子又稱為交叉微分算子,它是基于交叉差分的梯度算法,通過(guò)局部差分計(jì)算檢測(cè)邊緣線條。常用來(lái)處理具有陡峭的低噪聲圖像,當(dāng)圖像邊緣接近于正 45 度或負(fù) 45 度時(shí),該算法處理效果更理想。其缺點(diǎn)是對(duì)邊緣的定位不太準(zhǔn)確,提取的邊緣線條較粗。

# 用robert方法進(jìn)行邊緣檢測(cè)

dst = cv2.addWeighted(absX,0.5,absY,0.5,0)

# cv2.imshow("dst", dst)

# 截圖后反轉(zhuǎn)

def inverse_color(image):

height, width, channels = image.shape

for row in range(height):

for list in range(width):

for c in range(channels):

pv = image[row, list, c]

image[row, list, c] = 255 - pv

cv.imshow("result", image)

three = cv.imread ("3.jpg")

inverse_color(three)

四:投影

投影就是就是把一個(gè)場(chǎng)景投影到攝像機(jī)的像平面上。類型有透視投影,仿射投影,弱透視投影與類透視投影等。

在opencv中,投影主要分為水平投影和垂直投影。水平投影是二維圖像在y軸上的投影;垂直投影是二維圖像在x軸上的投影。

在水平和垂直的方向上進(jìn)行投影,先將投影的圖像轉(zhuǎn)化為灰度圖,然后進(jìn)行二值化閾值分割,之后在水平和垂直的方向上進(jìn)行投影。所用庫(kù)為cv2以及matplotlib數(shù)據(jù)分析庫(kù)進(jìn)行操作。

步驟如下:

1.顯示原圖

import cv2

import numpy as np

from matplotlib import pyplot as plt

img=cv2.imread('123.jpg')

2.垂直方向投影

img=cv2.imread('123.jpg') #讀取圖片,裝換為可運(yùn)算的數(shù)組

GrayImage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #將BGR圖轉(zhuǎn)為灰度圖

ret,thresh1=cv2.threshold(GrayImage,130,255,cv2.THRESH_BINARY)#將圖片進(jìn)行二值化(130,255)之間的點(diǎn)均變?yōu)?55(背景)

(h,w)=thresh1.shape #返回高和寬

a = [0 for z in range(0, w)]

#記錄每一列的波峰

for j in range(0,w): #遍歷一列

for i in range(0,h): #遍歷一行

if thresh1[i,j]==0: #如果改點(diǎn)為黑點(diǎn)

a[j]+=1 #該列的計(jì)數(shù)器加一計(jì)數(shù)

thresh1[i,j]=255 #記錄完后將其變?yōu)榘咨?/p>

for j in range(0,w): #遍歷每一列

for i in range((h-a[j]),h): #從該列應(yīng)該變黑的最頂部的點(diǎn)開始向最底部涂黑

thresh1[i,j]=0 #涂黑

plt.imshow(thresh1,cmap=plt.gray())

plt.show()

cv2.imshow('one',thresh1)

cv2.waitKey(0)

3.水平方向投影

for j in range(0,h):

for i in range(0,w):

if thresh1[j,i]==0:

a[j]+=1

thresh1[j,i]=255

for j in range(0,h):

for i in range(0,a[j]):

thresh1[j,i]=0

plt.imshow(thresh1,cmap=plt.gray())

plt.show()

五:車牌字符分割

車牌識(shí)別系統(tǒng)(Vehicle License Plate Recognition,VLPR) 是計(jì)算機(jī)視頻圖像識(shí)別技術(shù)在車輛牌照識(shí)別中的一種應(yīng)用。

車牌識(shí)別技術(shù)要求能夠?qū)⑦\(yùn)動(dòng)中的汽車牌照從復(fù)雜背景中提取并識(shí)別出來(lái),通過(guò)車牌提取、圖像預(yù)處理、特征提取、車牌字符識(shí)別等技術(shù),識(shí)別車輛牌號(hào)、顏色等信息,目前最新的技術(shù)水平為字母和數(shù)字的識(shí)別率可達(dá)到99.7%,漢字的識(shí)別率可達(dá)到99%。

要將車牌進(jìn)行字符分割,先進(jìn)行字符識(shí)別操作。這里進(jìn)行的是直接用方框識(shí)別并括起來(lái)。需要的步驟是首先要讓彩色的車牌圖像轉(zhuǎn)化為灰度圖,再反色,閾值分割,再利用水平和垂直方向的投影依次截取需要的小方框的長(zhǎng)和寬,進(jìn)行識(shí)別。用到的技術(shù)是python+opencv其中的cv2庫(kù)以及數(shù)據(jù)分析numpy庫(kù)。

步驟如下:

1.讀取原圖

import cv2

import cv2 as cv

import numpy as np

image1 = cv.imread('123456.jpg',1)

cv.imshow('image1', image1)

2.灰度轉(zhuǎn)換

然后把圖片轉(zhuǎn)化為灰度圖,這里設(shè)置讀取圖片用灰度圖片讀取即可。

image2 = cv.imread('123456.jpg',0)

cv.imshow('image2', image2)

3.反色

接著將圖像進(jìn)行反色,記錄寬高和深度,并用255減去灰度圖顏色的寬高。

height, width, deep = image1.shape

dst = np.zeros((height,width,1), np.uint8)

for i in range(0, height):

for j in range(0, width):

grayPixel = image2[i, j]

dst[i, j] = 255-grayPixel

cv2.imshow('image3', dst)

4.閾值分割

然后將反色后的圖像進(jìn)行閾值分割,閾值設(shè)為100。

ret, thresh = cv2.threshold(dst, 100, 255, cv2.THRESH_TOZERO)

cv2.imshow('image4', thresh)

5.投影

之后在水平和垂直方向上進(jìn)行投影,畫出投影圖,并記錄投影小黑點(diǎn)的單位起始長(zhǎng)度數(shù)組,設(shè)定兩個(gè)函數(shù),返回之后要用到的每個(gè)小分割矩形的特征點(diǎn)坐標(biāo)值。

# 水平方向投影

def hProject(binary):

h, w = binary.shape

# 水平投影

hprojection = np.zeros(binary.shape, dtype=np.uint8)

# 創(chuàng)建h長(zhǎng)度都為0的數(shù)組

h_h = [0]*h

for j in range(h):

for i in range(w):

if binary[j,i] == 0:

h_h[j] += 1

# 畫出投影圖

for j in range(h):

for i in range(h_h[j]):

hprojection[j,i] = 255

return h_h

# 垂直反向投影

def vProject(binary):

h, w = binary.shape

# 垂直投影

vprojection = np.zeros(binary.shape, dtype=np.uint8)

# 創(chuàng)建 w 長(zhǎng)度都為0的數(shù)組

w_w = [0]*w

for i in range(w):

for j in range(h):

if binary[j, i ] == 0:

w_w[i] += 1

for i in range(w):

for j in range(w_w[i]):

vprojection[j,i] = 255

return w_w

6.字符識(shí)別匹配分割

根據(jù)返回的數(shù)組,確定分割位置,進(jìn)行字符識(shí)別匹配分割。

th = thresh

h,w = th.shape

h_h = hProject(th)

start = 0

h_start, h_end = [], []

position = []

# 根據(jù)水平投影獲取垂直分割

for i in range(len(h_h)):

if h_h[i] > 0 and start == 0:

h_start.append(i)

start = 1

if h_h[i] ==0 and start == 1:

h_end.append(i)

start = 0

for i in range(len(h_start)):

cropImg = th[h_start[i]:h_end[i], 0:w]

if i ==0:

pass

w_w = vProject(cropImg)

wstart , wend, w_start, w_end = 0, 0, 0, 0

for j in range(len(w_w)):

if w_w[j] > 0 and wstart == 0:

w_start = j

wstart = 1

wend = 0

if w_w[j] ==0 and wstart == 1:

w_end = j

wstart = 0

wend = 1

# 當(dāng)確認(rèn)了起點(diǎn)和終點(diǎn)之后保存坐標(biāo)

if wend == 1:

position.append([w_start, h_start[i], w_end, h_end[i]])

wend = 0

# 確定分割位置

for p in position:

cv2.rectangle(thresh, (p[0], p[1]), (p[2], p[3]), (0, 0, 255), 2)

cv2.imshow('image7', thresh)

cv.waitKey(0)

總結(jié)

以上是生活随笔為你收集整理的python 视觉技术_python+opencv实现机器视觉基础技术(边缘提取,图像滤波,边缘检测算子,投影,车牌字符分割)...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。