計算機視覺第一課opencv(三)保姆級教學

簡介

計算機視覺第一課opencv(一)保姆級教學

計算機視覺第一課opencv(二)保姆級教學

今天繼續學習opencv。

一、?圖像形態學

????????什么是形態學:圖像形態學是一種處理圖像形狀特征的圖像處理技術,主要用于描述和處理圖像中的形狀和結構。形態學可以用于提取圖像中的特征、消除噪聲、改變圖像的形狀等。

1.腐蝕

????????正如這個名字表面上的意思,侵蝕的基本思想就像土壤侵蝕一樣,它侵蝕了前景物體foreground object 的邊界(在這,我們會讓前景保持為白色)。那么侵蝕的作用是什么呢?這樣內核可以在圖像中滑動(在二維卷積中)。只有當內核下的所有像素都為1時,原始圖像中的像素(要么為1,要么為0)才會被認為是1,否則會被侵蝕(變成0)。這樣的結果就是,取決于內核的大小,邊界附近的所有像素都會被丟棄。因此,前景對象的厚度或大小會減少,或者只是簡單地讓圖像中的白色區域減少。它對于去除小的白色噪音(正如我們在顏色空間colorspace 疑問中看到的那樣),分離兩個連接的物體等都很有用。

????????腐蝕作用:可以用來消除小且無意義的物體。在這里,作為一個例子,我將使用一個包含內部全都是1的3x3內核。讓我們看看它產生什么樣的變化。

原圖

# 1、圖像腐蝕,函數為:
# cv2.erode(src, kernel, dst,anchor,iterations,borderType,borderValue)
# src: 輸入的圖像
# kernel: 用于腐蝕的結構元件如果element = Mat(), 則使用3 x 3的矩形結構單元。
# dst: 它是與src相同大小和類型的輸出圖像。
# iterations: 腐蝕操作的迭代次數,默認為1。次數越多, 腐蝕操作執行的次數越多,腐蝕效果越明顯import numpy as np
sun = cv2.imread('sun.png')
cv2.imshow('src',sun)
cv2.waitKey(0)
kernel = np.ones((3,3),np.uint8)  # 這里kernel大小,修改為5*5試試
erosion_1 = cv2.erode(sun,kernel,iterations=2)  #iterations改為5試試
cv2.imshow('erosion_1',erosion_1)
cv2.waitKey(0)

2.膨脹

????????膨脹操作正好與腐蝕相反。這里,如果內核下至少有一個像素是“1”,那么該像素元素就是“1”。因此,它增加了圖像中的白色區域,或則說增加了前景目標對象的尺寸大小。通常情況下,在去除噪聲以后,在腐蝕操作之后就是膨脹。因為,腐蝕消除了白色的噪音,但它也縮小了我們的前景物體,所以我們需要擴大回它。因為當噪音消失了,原本應該存在的白色面積也不會自主回來。而且膨脹在連接物體的破碎部分時也很有用。

# 2、圖像膨脹, 函數為:
# cv2.dilate(img, kernel, iteration)
# 參數含義:
# img – 目標圖片
# kernel – 進行操作的內核,默認為3×3的矩陣
# iterations – 膨脹次數,默認為1wenzi = cv2.imread('wenzi.png')
cv2.imshow('src1',wenzi)
cv2.waitKey(0)
kernel = np.ones((2,2),np.uint8)  # 這里kernel大小
wenzi_new = cv2.dilate(wenzi,kernel,iterations=2)
cv2.imshow('wenzi_new',wenzi_new)
cv2.waitKey(0)

3.開運算

????????先進行腐蝕,再進行膨脹就叫做開運算。 通常情況下,含有噪聲的圖像二值化后,得到的邊界是不平滑的,物體區域具有一些錯判的孔洞,背景區域散布著一些小的噪聲物體。對一個圖像先進行腐蝕運算然后再膨脹的操作過程稱為開運算,它可以消除細小的物體、在纖細點處分離物體、平滑較大物體的邊界時不明顯的改變其面積。

????????在做對指紋識別的時候,遇到這樣的圖片對我們的識別效果影響不好,太多嘈雜的點了,我們就需要對其進行開運算。

# 開運算:先腐蝕后膨脹  作用:平滑物體的輪廓、斷開較窄的狹頸并消除細的突出物。
zhiwen = cv2.imread('zhiwen.png')
cv2.imshow('src2',zhiwen)
cv2.waitKey(0)
kernel = np.ones((2,2),np.uint8)  #設置kenenl大小
zhiwen_new = cv2.morphologyEx(zhiwen,cv2.MORPH_OPEN,kernel) #開運算
cv2.imshow('zhiwen_new',zhiwen_new)
cv2.waitKey(0)

4.閉運算

????????先膨脹再腐蝕。它經常被用來填充前景物體中的小洞,或者前景物體上面的小黑點。

????????對于這樣的指紋,我們發現它中間好多斷開了,有很多空洞不太符合我們正常的指紋,需要進行閉運算進行處理

# # 閉運算:先膨脹后腐蝕  作用:彌合較窄的間斷和細長的溝壑,消除小的孔洞,填補輪廓線中的斷裂。
zhiwen_duan = cv2.imread('zhiwen_duan.png')
cv2.imshow('src3',zhiwen_duan)
cv2.waitKey(0)
kernel = np.ones((4,4),np.uint8)  #設置kenenl大小
zhiwen_new = cv2.morphologyEx(zhiwen_duan,cv2.MORPH_CLOSE,kernel) #閉運算
cv2.imshow('zhiwen_new1',zhiwen_new)
cv2.waitKey(0)
#

5.梯度運算

????????其實就是一幅圖像膨脹和腐蝕的差別。突出顯示圖像中強度變化劇烈的地方

wenzi = cv2.imread('wenzi.png')
cv2.imshow('wenzi_new',wenzi)
cv2.waitKey(0)
kernel = np.ones((2,2),np.uint8)  #設置kenenl大小
# 膨脹
pz_wenzi=cv2.dilate(wenzi,kernel,iterations=1)
cv2.imshow('pz_wenzi',pz_wenzi)
cv2.waitKey(0)
#腐蝕
fs_wenzi=cv2.erode(wenzi,kernel,iterations=1)
cv2.imshow('fs_wenzi',fs_wenzi)
cv2.waitKey(0)
# 膨脹-腐蝕
bianyuan = cv2.morphologyEx(wenzi,cv2.MORPH_GRADIENT,kernel)
cv2.imshow('bianyuan',bianyuan)
cv2.waitKey(0)
cv2.destroyAllWindows()

6.頂帽

頂帽 = 原始圖像 - 開運算結果(先腐蝕后膨脹)

sun = cv2.imread('sun.png')
cv2.imshow('sun_yuantu',sun)
cv2.waitKey(0)
kernel = np.ones((2,2),np.uint8)  #設置kenenel大小
#開運算
open_sun=cv2.morphologyEx(sun,cv2.MORPH_OPEN,kernel)
cv2.imshow('open_sun',open_sun)
cv2.waitKey(0)
#頂帽
tophat = cv2.morphologyEx(sun,cv2.MORPH_TOPHAT,kernel)
cv2.imshow('TOPHAT',tophat)
cv2.waitKey(0)

7.黑帽

sun = cv2.imread('sun.png')
cv2.imshow('sun_yuantu',sun)
cv2.waitKey(0)
kernel = np.ones((2,2),np.uint8)  #設置kenenel大小
# #閉運算
close_sun=cv2.morphologyEx(sun,cv2.MORPH_CLOSE,kernel)
cv2.imshow('close_sun',close_sun)
cv2.waitKey(0)
#黑帽
blackhat = cv2.morphologyEx(sun,cv2.MORPH_BLACKHAT,kernel)
cv2.imshow('BLACKHAT',blackhat)
cv2.waitKey(0)

二、圖像邊緣檢測

????????邊緣檢測:是圖形圖像處理、計算機視覺和機器視覺中的一個基本工具,通常用于特征提取和特征檢測,旨在檢測一張數字圖像中有明顯變化的邊緣或者不連續的區域。

1.Sobel算子

????????Sobel 算子是一種離散的微分算子,該算子結合了高斯平滑和微分求導運算。該算子利用局部差分尋找邊緣,計算所得的是一個梯度的近似值。Sobel算子包含2組3×3的矩陣,分別為橫向和縱向模板,將之與圖像作平面卷積,即可分別得出橫向及縱向的亮度差分近似值。

# sobel算子
# cv2.Sobel(src, ddepth, dx, dy[, ksize[, scale[, delta[, borderType]]]])
# 參數:
# src: 輸入圖像
# ddepth: 輸出圖像的深度(可以理解為數據類型),-1表示與原圖相同的深度
# dx,dy: 當組合為dx=1,dy=0時為x方向的一階導數,當組合為dx=0,dy=1時為y方向的一階導數(如果同時為1,通常效果不佳)
# ksize:(可選參數)Sobel算子的大小,必須是1,3,5或者7,默認為3。yuan = cv2.imread('yuan.png',0)
yuan = cv2.resize(yuan,dsize=None,fy=0.5,fx=0.5)
cv2.imshow('yuan',yuan)
cv2.waitKey(0)
# # x方向上的邊緣
yuan_x = cv2.Sobel(yuan,-1,dx=1,dy=0)
cv2.imshow('yuan_x',yuan_x)
cv2.waitKey(0)
# x方向上的邊緣,包括負數信息(右減),但顯示不出來,因為范圍是(0~255)
yuan_x_64 = cv2.Sobel(yuan,cv2.CV_64F,dx=1,dy=0)#數據uint8改為float64,可保存負數
cv2.imshow('yuan_x_64',yuan_x_64)
cv2.waitKey(0)
# #x方向上的邊緣,包括負數信息,進行取絕對值的操作,右端的負值信息就可以顯示出來了
yuan_x_full = cv2.convertScaleAbs(yuan_x_64)#轉換為絕對值,負數轉換為正數
cv2.imshow('yuan_x_full',yuan_x_full)
cv2.waitKey(0)
# # y方向上的邊緣
yuan_y = cv2.Sobel(yuan,-1,dx=0,dy=1)
cv2.imshow('yuan_y',yuan_y)
cv2.waitKey(0)
# y方向上的邊緣,包括負數信息(下減),但顯示不出來,因為范圍是(0~255)
yuan_y_64 = cv2.Sobel(yuan,cv2.CV_64F,dx=0,dy=1)#數據uint8改為float64,可保存負數
yuan_y_full = cv2.convertScaleAbs(yuan_y_64)#轉換為絕對值,負數轉換為正數
cv2.imshow('yuan_y_full',yuan_y_full)
cv2.waitKey(0)
# # 如果同時使用x,y方向的結果如何呢?(不建議使用!)
yuan_xy = cv2.Sobel(yuan,-1,dx=1,dy=1)
cv2.imshow('yuan_xy',yuan_xy)
cv2.waitKey(0)
# # 使用圖像加權運算組合x和y方向的2個邊緣。
yuan_xy_full = cv2.addWeighted(yuan_x_full, 1,yuan_y_full, 1, gamma=0)
cv2.imshow('yuan_xy_full',yuan_xy_full)
cv2.waitKey(0)

dama = cv2.imread('dama.jpg', 0)#不用灰度試試效果
dama=cv2.resize(dama,dsize=None,fx=0.5,fy=0.5)
dama_x_64 = cv2.Sobel(dama,cv2.CV_64F,dx=1,dy=0)#默認int8改為float64,可保存負數
dama_x_full = cv2.convertScaleAbs(dama_x_64)#轉換為絕對值,負數轉換為正數
dama_y_64 = cv2.Sobel(dama,cv2.CV_64F,dx=0,dy=1)#默認int8改為float64,可保存負數
dama_y_full = cv2.convertScaleAbs(dama_y_64)#轉換為絕對值,負數轉換為正數
dama_xy_sobel_full = cv2.addWeighted(dama_x_full, 1,dama_y_full, 1, 0)cv2.imshow('dama_xy_sobel_full',dama_xy_sobel_full)
cv2.waitKey(0)

2.Scharr 算子

????????Scharr 算子是 Soble 算子在 ksize=3 時的優化,與 Soble 的速度相同,且精度更高。Scharr 算子與 Sobel 算子的不同點是在平滑部分,其中心元素占的權重更重,相當于使用較小標準差的高斯函數,也就是更瘦高的模板。

dama = cv2.imread('dama.jpg',cv2.IMREAD_GRAYSCALE) #Scharr算子
# zl=cv2.cvtColor(zl,cv2.COLOR_BGR2GRAY)
dama_x_64 = cv2.Scharr(dama,cv2.CV_64F,dx=1,dy=0)#默認int8改為float64,可保存負數
dama_x_full = cv2.convertScaleAbs(dama_x_64)#轉換為絕對值,負數轉換為正數
dama_y_64 = cv2.Scharr(dama,cv2.CV_64F,dx=0,dy=1)#默認int8改為float64,可保存負數
dama_y_full = cv2.convertScaleAbs(dama_y_64)#轉換為絕對值,負數轉換為正數
dama_xy_Scharr_full = cv2.addWeighted(dama_x_full, 1,dama_y_full, 1, 0)
cv2.imshow('dama_xy_Scharr_full',dama_xy_Scharr_full)
cv2.waitKey(0)

3.Laplacian算子

????????不再以x和y的方向計算,而是以圓方向計算變化率。因此不需要Gx+Gy。

# ###### cv2.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])
# ###### # src: 輸入圖像,可以是灰度圖像,也可以是多通道的彩色圖像
# ###### # ddepth: 輸出圖片的數據深度;
# ###### # ksize: 計算二階導數濾波器的孔徑大小,必須為正奇數,可選項
# ###### # scale: 縮放比例因子,可選項,默認值為 1
# ###### # delta: 輸出圖像的偏移量,可選項,默認值為 0
# ###### #
#
dama= cv2.imread('yuan.png',cv2.IMREAD_GRAYSCALE)
dama_lap = cv2.Laplacian(dama,cv2.CV_64F)
dama_lap_full = cv2.convertScaleAbs(dama_lap)#轉換為絕對值,負數轉換為正數
cv2.imshow('dama_lap_full',dama_lap_full)
cv2.waitKey(0)

4.Canny邊緣檢測

√ 低錯誤率。因為一般的邊緣檢測算子可能存在檢測到偽邊緣的情況,因此Canny算法檢測到的邊緣盡可能地是真實的邊緣。

√ 較好地定位邊緣點。由檢測器標記的邊緣點與真實邊緣點中心盡可能地接近。

√ 單一的邊緣響應。圖像中的邊緣只標記出一次。

1.圖像降噪

????????圖像去噪是進行邊緣檢測的第一步,通過去噪可以去除圖像中的一些噪點,從而使邊緣檢測時免受噪點干擾。高斯濾波

2.梯度計算

????????要進行邊緣檢測,就需要得到圖像梯度信息,根據圖像的梯度幅值和梯度方向來確定邊緣,一般均采用sobel算子對圖像進行梯度幅值與梯度方向計算。

3.非極大值抑制NMS(Non-Maximal Suppression)

????????一階微分在灰度值斜坡過渡時不為零且存在較粗的邊緣,較粗的邊緣會增大邊緣檢測的誤差,因此需要細化邊緣,一種較為常用的方法是非極大值抑制。非極大值抑制:即在梯度圖像中尋找梯度方向上的最大值作為邊緣,不是梯度方向上的最大值則抑制為0。因為梯度方向是灰度變化最大的方向。比較梯度圖像中每一點的灰度值與梯度方向上至少兩個梯度圖像像素點灰度值的大小,根據上述大小關系來確定是否保留該點的灰度值。

4.雙閾值邊界跟蹤

????????雙閾值處理就是根據實際情況需要設置一個灰度高閾值和一個灰度低閾值對NMS后的圖像進行過濾,使得得到的邊緣盡可能是真實的邊緣。雙閾值的基本處理步驟為:

????????當然上面這些不需要我們寫代碼進行一步一步處理,只需要調用Canny邊緣檢測的函數會自己計算、我們只要簡單了解有哪些過程就行。每一個過程有啥用

# ###### canny邊緣檢測
# ###### cv2.Canny(image, threshold1, threshold2[, apertureSize[, L2gradient]])
# ###### # image 為輸入圖像。
# ###### # threshold1 表示處理過程中的第一個閾值。
# ###### # threshold2 表示處理過程中的第二個閾值。
# ###### #
#
zl = cv2.imread('dama.jpg',cv2.IMREAD_GRAYSCALE)
zl=cv2.resize(zl,dsize=None,fy=0.5,fx=0.5)
cv2.imshow('dama',zl)
cv2.waitKey(0)
zl_canny = cv2.Canny(zl, 150, 230)#低,高
cv2.imshow('dama_canny',zl_canny)
cv2.waitKey(0)

總結

????????讀者可以使用自己的圖片進行測試,在邊緣檢測上Canny邊緣檢測相對于前三個具有更好的檢測效果。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/96325.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/96325.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/96325.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

24.早期目標檢測

早期目標檢測 第一步,計算機圖形學做初步大量候選框,把物體圈出來 第二步,依次將所有的候選框圖片,輸入到分類模型進行判斷 選擇性搜索 選擇搜索算法(Selective Search),是一種熟知的計算機圖像…

Java基礎知識點匯總(三)

一、面向對象的特征有哪些方面 Java中面向對象的特征主要包括以下四個核心方面:封裝(Encapsulation) 封裝是指將對象的屬性(數據)和方法(操作)捆綁在一起,隱藏對象的內部實現細節&am…

GEO優化專家孟慶濤:讓AI“聰明”選擇,為企業“精準”生長

在生成式AI席卷全球的今天,企業最常遇到的困惑或許是:“為什么我的AI生成內容總像‘模板套娃’?”“用戶明明想要A,AI卻拼命輸出B?”當生成式AI從“能用”邁向“好用”的關鍵階段,如何讓AI真正理解用戶需求…

【交易系統系列04】交易所版《速度與激情》:如何為狂飆的BTC交易引擎上演“空中加油”?

交易所版《速度與激情》:如何為狂飆的BTC交易引擎上演“空中加油”? 想象一下這個場景:你正端著一杯熱氣騰騰的咖啡,看著窗外我家那只貪睡的橘貓趴在陽光下打著呼嚕。突然,手機上的警報開始尖叫,交易系統監…

windows下jdk環境切換為jdk17后,臨時需要jdk1.8的處理

近段時間,終于決定把開發環境全面轉向jdk17,這不就遇到了問題。 windows主環境已經設置為jdk17了。 修改的JAVA_HOME D:\java\jdk-17CLASSPATH設置 .;D:\java\jdk-17\lib\dt.jar;D:\java\jdk-17\lib\tools.jar;PATH中增加 D:\java\jdk-17\bin但是有些程序…

Android URC 介紹及源碼案例參考

1. URC 含義 URC 是 Unsolicited Result Code(非請求結果碼)的縮寫。 它是 modem(基帶)在不需要 AP 主動請求的情況下向上層主動上報的消息。 典型例子:短信到達提示、網絡狀態變更、來電通知、信號質量變化等。 URC 一般以 AT 命令擴展的形式從 modem 發到 AP,例如串口…

VB.NET發送郵件給OUTLOOK.COM的用戶,用OUTLOOK.COM郵箱賬號登錄給別人發郵件

在VB.NET中通過代碼發送郵件時,確實會遇到郵箱服務的身份認證(Authentication)要求。特別是微軟Outlook/Hotmail等服務,已經逐步禁用傳統的“基本身份驗證”(Basic Authentication),轉而強制要求…

【網絡運維】Shell:變量進階知識

Shell 變量進階知識 Shell 中的特殊變量 位置參數變量 Shell 腳本中常用的位置參數變量如下: $0:獲取當前執行的 Shell 腳本文件名(包含路徑時包括路徑)$n:獲取第 n 個參數值(n>9 時需使用 ${n}&#xf…

部署Qwen2.5-VL-7B-Instruct-GPTQ-Int3

模型下載 from modelscope import snapshot_download model_dir snapshot_download(ChineseAlpacaGroup/Qwen2.5-VL-7B-Instruct-GPTQ-Int3)相關包導入 import os import numpy as np import pandas as pd from tqdm import tqdm from datetime import datetime,timedelta fro…

sourcetree 拉取代碼

提示:文章旨在于教授大家 sourcetree 拉取代碼的方式,關于代碼的提交合并等操作后續會補充。 文章目錄前言一、sourcetree 安裝二、http 與 ssh 拉取代碼1.http 方式(1)生成 token(2)拼接項目的 url&#x…

epoll模型網絡編程知識要領

1、程序初始化創建監聽socket調用bind函數綁定ip地址、port端口號調用listen函數監聽調用epoll_create函數創建epollfd調用epoll_ctrl函數將listenfd綁定到epollfd上,監測listenfd的讀事件在一個無限循環中,調用epoll_wait函數等待事件發生2、處理客戶端…

15-day12LLM結構變化、位置編碼和投機采樣

多頭機制transformer結構歸一化層選擇 歸一化層位置歸一化層類型激活函數Llama2結構MoE架構 混合專家模型DeepSeek MLA為何需要位置編碼目前的主流位置編碼正余弦位置編碼可學習位置編碼ROPE旋轉位置編碼推導參考: https://spaces.ac.cn/archives/8265 https://zhua…

記錄 docker容器打包成鏡像 在其他服務器快速啟動鏡像和容器

我有個nginx服務器 需要在其他服務器直接部署使用 里面都是完整的 使用 docker ps 查看容器id 進行打包成鏡像docker commit [容器ID或名稱] 新鏡像名:版本 docker commit 28f60e2206b2 my-nginx-custom:v1鏡像保存成文件 docker save -o my-nginx-custom.tar my-nginx-custom:…

使用LLaMA-Factory對大模型進行微調-詳解

書接上回 啟動llama Factory可視化頁面 llamafactory-cli webui 如果想后臺運行 使用 nohup llamafactory-cli webui &瀏覽器訪問 http://127.0.0.1:7860/配置項主要參數: 參考: https://docs.coreshub.cn/console/compute_platform/help/llama_factory/ 模型路徑 : 解…

【AI】錄制自動生成UI自動化腳本

命令行輸入:npx playwright codegen https://myerp.dmyc.XXX.com:9443/打開的瀏覽器上操作,會自動錄制,并生成自動化腳本

深度剖析字節跳動VeOmni框架

背景與設計動機 隨著推薦系統和AI模型走向多模態、多任務的趨勢,字節跳動面臨著訓練、迭代效率和系統復雜度的雙重挑戰。一方面,各類業務(如新聞推薦、短視頻、圖文廣告、電商帶貨等)都需要處理文本、圖像、視頻、音頻等多種輸入模…

OCR庫pytesseract安裝保姆級教程

本文將介紹使用工具安裝OCR庫pytesseract的詳細流程。 Anaconda安裝教程參考Anaconda安裝保姆級教程。 目錄 一、工具安裝 二、創建虛擬環境 三、安裝pytesseract 總結 一、工具安裝 點擊鏈接前往官網codetou.com,下載安裝最新版即可,本篇博客以摳頭…

開源im即時通訊軟件開發社交系統全解析:安全可控、功能全面的社交解決方案

在即時通訊與社交需求日益增長的今天,一款安全、穩定、功能全面的聊天軟件成為不少團隊和開發者的剛需。但市面上多數聊天 APP 要么依賴第三方插件,面臨數據安全隱患和高額服務費;要么功能單一,難以滿足復雜社交場景。今天給大家推…

殘差神經網絡(ResNet)

殘差神經網絡(Residual Neural Network,簡稱 ResNet)是深度學習領域的里程碑式模型,由何凱明等人在 2015 年提出,成功解決了深層神經網絡訓練中的梯度消失 / 爆炸問題,使訓練超深網絡(如 152 層…

學習嵌入式之驅動

一、基礎搭建1.基礎:c語言 軟件編程語言 數據結構 軟件編程思想2.驅動實現目標如果將Linux系統細致到開發板平臺上? Liunx系統與硬件設備的適配3.自我能力的鍛煉繼續強化C語言鍛煉大型代碼閱讀和分析能力學習大型項目的代碼搭建和管理的能力…