OpenCV(05)直方圖均衡化,模板匹配,霍夫變換,圖像亮度變換,形態學變換

【OpenCV(01)】基本圖像操作、繪制,讀取視頻

【OpenCV(02)】圖像顏色處理,灰度化,二值化,仿射變換

【OpenCV(03)】插值方法,邊緣填充,透視變換,水印制作,噪點消除

【OpenCV(04)】梯度處理,邊緣檢測,繪制輪廓,凸包特征檢測,輪廓特征查找

目錄

  • 直方圖
  • 什么是直方圖
  • 繪制直方圖
  • 直方圖均衡化
    • 自適應均衡化
    • 對比度受限的自適應均衡化
  • 模板匹配
    • 匹配方法
      • 平方差匹配
      • 歸一化平方差匹配
      • 相關匹配
      • 歸一化相關匹配
      • 相關系數匹配
      • 歸一化相關系數匹配
    • 繪制輪廓
  • 霍夫變換
    • 標準霍夫變換
    • 統計概率霍夫直線變換
    • 霍夫圓變換
  • 圖像亮度變換
    • 亮度變換
    • 線性變換
    • 直接像素值修改
  • 形態學變換

直方圖

什么是直方圖

  • 直方圖:反映圖像像素分布的統計圖,橫坐標就是圖像像素的取值,縱坐標是該像素的個數。也就是對一張圖像中不同像素值的像素個數的統計。
  • 增加對比度:黑的更黑,白的更白。
    在這里插入圖片描述

繪制直方圖

  1. 繪制直方圖:hist=cv2.calcHist(images, channels, mask, histSize, ranges)
  • images:輸入圖像列表,可以是一幅或多幅圖像(通常是灰度圖像或者彩色圖像的各個通道)。
  • channels:一個包含整數的列表,指示在每個圖像上計算直方圖的通道編號。如果輸入圖像是灰度圖,它的值就是 [0];如果是彩色圖像的話,傳入的參數可以是 [0],[1],[2] 它們分別對應著通道 B,G,R。
  • mask(可選):一個與輸入圖像尺寸相同的二值掩模圖像,其中非零元素標記了參與直方圖計算的區域,None為全部計算。
  • histSize:一個整數列表,也就是直方圖的區間個數(BIN 的數目)。用中括號括起來,例如:[256]。
  • ranges:每維數據的取值范圍,它是一個二維列表,每一維對應一個通道的最小值和最大值,例如對灰度圖像可能是 [0, 256]

返回值hist 是一個長度為255的數組,數組中的每個值表示圖像中對應灰度等級的像素計數

  1. minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(hist)
    獲取直方圖的最小值、最大值及其對應最小值的位置索引、最大值的位置索引

  2. cv2.line(img, pt1, pt2, color, thickness)

  • img:原始圖像,即要在上面畫線的numpy數組(一般為uint8類型)。
  • pt1pt2:分別為線段的起點和終點坐標,它們都是元組類型,例如 (x1, y1)(x2, y2) 分別代表線段兩端的橫縱坐標。
  • color:線段的顏色,通常是一個包含三個元素的元組 (B, G, R) 表示BGR色彩空間的像素值,也可以是灰度圖像的一個整數值。
  • thickness:線段的寬度,默認值是1,如果設置為負數,則線寬會被填充。
import cv2 as cv
import numpy as np#讀圖
bg = cv.imread('E:\hqyj\code\opencv\images\\bg.png')
#創建黑圖,繪制直方圖
black = np.zeros((256,256,3),np.uint8)#統計像素
hist = cv.calcHist([bg],[0],None,[256],[0,256])
print(hist)#獲取直方圖的最小值、最大值及其對應的最小值的位置索引、最大值的位置索引
minval,maxval,minloc,maxloc = cv.minMaxLoc(hist)#由于直方圖只有一列,列索引始終為 0,行索引則對應于具體的灰度值
#最小值 461.0 出現在位置 (0, 249),即灰度值為 249 的像素頻率為 0。
#最大值 32380.0 出現在位置 (0, 5),即灰度值為 5 的像素頻率為 5000
print(minval,maxval,minloc,maxloc)#定義直方圖的高
h_hist = np.int32(256)#循環遍歷每一個灰度值 
for i in range(256):#當前像素的個數占直方圖的高,歸一化處理l = int(hist[i].item()*h_hist/maxval)point1 = (i,256-l)point2 = (i,256)cv.line(black,point1,point2,(255,255,0),1)cv.imshow('dst',black)
cv.waitKey(0)
cv.destroyAllWindows()

直方圖均衡化

遍歷圖像的像素統計出灰度值的個數、比例與累計比例,并重新映射到0-255范圍(也可以是其他范圍)內,其實從觀感上就可以發現,下面兩幅圖中前面那幅圖對比度不高,偏灰白。
直方圖均衡化作用:

  • 增強對比度
  • 提高圖像質量

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

自適應均衡化

自適應直方圖均衡化(Adaptive Histogram Equalization, AHE),通過調整圖像像素值的分布,使得圖像的對比度和亮度得到改善。

具體過程如下所示:
在這里插入圖片描述
設有一個3*3的圖像,其灰度圖的像素值如上圖所示,現在我們要對其進行直方圖均衡化,首先就是統計其每個像素值的個數、比例以及其累計比例。如下圖所示。
在這里插入圖片描述
接下來我們就要進行計算,就是將要縮放的范圍(通常是縮放到0-255,所以就是255-0)乘以累計比例,得到新的像素值,并將新的像素值放到對應的位置上,比如像素值為50的像素點,將其累計比例乘以255,也就是0.33乘以255得到84.15,取整后得到84,并將84放在原圖像中像素值為50的地方,像素值為100、210、255的計算過程類似,最終會得到如下圖所示的結果,這樣就完成了最基本的直方圖均衡化的過程。
在這里插入圖片描述
在這里插入圖片描述
dst = cv.equalizeHist(imgGray)

imgGray為需要直方圖均衡化的灰度圖,返回值為處理后的圖像

import cv2 as cv#讀圖
img = cv.imread('E:\hqyj\code\opencv\images\\zhifang.png',cv.IMREAD_GRAYSCALE)
#直方圖均衡化
dst = cv.equalizeHist(img)
cv.imshow('img',img)
cv.imshow('dst',dst)
cv.waitKey(0)
cv.destroyAllWindows()

對比度受限的自適應均衡化

因為全局調整亮度和對比度的原因,臉部太亮,大部分細節都丟失了。自適應均衡化就是用來解決這一問題的:它在每一個小區域內(默認8×8)進行直方圖均衡化。當然,如果有噪點的話,噪點會被放大,需要對小區域內的對比度進行了限制,所以這個算法全稱叫:對比度受限的自適應直方圖均衡化(Contrast Limited Adaptive Histogram Equalization, CLAHE)。
在這里插入圖片描述
clahe = cv2.createCLAHE(clipLimit=None, tileGridSize=None)

  • clipLimit(可選):對比度限制參數,用于控制直方圖均衡化過程中對比度增強的程度。如果設置一個大于1的值(如2.0或4.0),CLAHE會限制對比度增強的最大程度,避免過度放大噪聲。如果不設置,OpenCV會使用一個默認值。
  • tileGridSize(可選):圖像分塊的大小,通常是一個包含兩個整數的元組,如(8, 8),表示將圖像劃分成8x8的小塊進行獨立的直方圖均衡化處理。分塊大小的選擇會影響到CLAHE的效果以及處理速度。

創建CLAHE對象后,可以使用 .apply() 方法對圖像進行CLAHE處理:

img=clahe.apply(image)

  • image:要均衡化的圖像。
  • img均衡后的圖像
import cv2 as cvimg = cv.imread('E:\hqyj\code\opencv\images\\zhifang.png',cv.IMREAD_GRAYSCALE)
#創建clahe對象
clahe = cv.createCLAHE(clipLimit=2.0,tileGridSize=(8,8))
#使用clach調用apply()方法
cl1 = clahe.apply(img)
cv.imshow('old',img)
cv.imshow('dst',cl1)
cv.waitKey(0)
cv.destroyAllWindows()

模板匹配

  • 不會有邊緣填充。

  • 類似于卷積,滑動比較,挨個比較象素。

  • 返回結果大小是:目標圖大小-模板圖大小-1。

import cv2 as cv
import numpy as np#讀圖
img = cv.imread('E:\hqyj\code\opencv\images\\game.png')
gray_img = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
#print(gray_img.shape)		# (266, 283)temp = cv.imread('E:\hqyj\code\opencv\images\\temp.png')
gray_temp = cv.cvtColor(temp,cv.COLOR_BGR2GRAY)
#print(gray_temp.shape)			# (24, 18)
h,w = temp.shape[:2]#模板匹配 拿到匹配結果矩陣
res = cv.matchTemplate(gray_img,gray_temp,cv.TM_CCOEFF_NORMED)
#print(res.shape)			# (243, 266)#設置閾值
thresh = 0.8
#獲取匹配上的結果的索引
loc = np.where(res >= thresh)
#print(loc)		# (array([ 63,......,143]), array([ 87,......,173]))#解包,拿到成對的x y索引
#print(zip(*loc))		# <zip object at 0x000001C601C79BC0>
for i in zip(*loc):#print(i)		#x,y = i[1],i[0]#print(x,y)cv.rectangle(img, (x,y), (x+w,y+h), (0,255,255), 2)cv.imshow('img',img)
cv.waitKey(0)
cv.destroyAllWindows()

temp(模板圖):
temp
game(原圖):
在這里插入圖片描述
在game圖中用temp圖作為模板圖匹配得到目標圖:
在這里插入圖片描述

匹配方法

res=cv2.matchTemplate(image, templ, method)

  • image:原圖像,這是一個灰度圖像或彩色圖像(在這種情況下,匹配將在每個通道上獨立進行)。

  • templ:模板圖像,也是灰度圖像或與原圖像相同通道數的彩色圖像。

  • method:匹配方法,可以是以下之一:

    • cv2.TM_CCOEFF(平方差匹配)
    • cv2.TM_CCOEFF_NORMED(歸一化平方差匹配)
    • cv2.TM_CCORR(相關匹配)
    • cv2.TM_CCORR_NORMED(歸一化相關匹配)
    • cv2.TM_SQDIFF(相關系數匹配)
    • cv2.TM_SQDIFF_NORMED(cv2.TM_CCOEFF_NORMED)
    • 這些方法決定了如何度量模板圖像與原圖像子窗口之間的相似度。
  • 返回值res

    函數在完成圖像模板匹配后返回一個結果矩陣,這個矩陣的大小與原圖像不相同。矩陣的每個元素表示原圖像中相應位置與模板圖像匹配的相似度。

    匹配方法不同,返回矩陣的值的含義也會有所區別。以下是幾種常用的匹配方法及其返回值含義:

    1. cv2.TM_SQDIFFcv2.TM_SQDIFF_NORMED

      返回值越接近0,表示匹配程度越好。最小值對應的最佳匹配位置。

    2. cv2.TM_CCORRcv2.TM_CCORR_NORMED

      返回值越大,表示匹配程度越好。最大值對應的最佳匹配位置。

    3. cv2.TM_CCOEFFcv2.TM_CCOEFF_NORMED

      返回值越大,表示匹配程度越好。最大值對應的最佳匹配位置。

平方差匹配

cv2.TM_SQDIFF

以模板圖與目標圖所對應的像素值使用平方差公式來計算,其結果越小,代表匹配程度越高,計算過程舉例如下。

注意:模板匹配過程皆不需要邊緣填充,直接從目標圖像的左上角開始計算。
在這里插入圖片描述

歸一化平方差匹配

cv2.TM_SQDIFF_NORMED

與平方差匹配類似,只不過需要將值統一到0到1,計算結果越小,代表匹配程度越高,計算過程舉例如下。
在這里插入圖片描述

相關匹配

cv2.TM_CCORR

使用對應像素的乘積進行匹配,乘積的結果越大其匹配程度越高,計算過程舉例如下。
在這里插入圖片描述

歸一化相關匹配

cv2.TM_CCORR_NORMED

與相關匹配類似,只不過是將其值統一到0到1之間,值越大,代表匹配程度越高,計算過程舉例如下。
在這里插入圖片描述

相關系數匹配

cv2.TM_CCOEFF

需要先計算模板與目標圖像的均值,然后通過每個像素與均值之間的差的乘積再求和來表示其匹配程度,1表示完美的匹配,-1表示最差的匹配,計算過程舉例如下。
在這里插入圖片描述

歸一化相關系數匹配

cv2.TM_CCOEFF_NORMED

也是將相關系數匹配的結果統一到0到1之間,值越接近1代表匹配程度越高,計算過程舉例如下。
在這里插入圖片描述

繪制輪廓

找的目標圖像中匹配程度最高的點,我們可以設定一個匹配閾值來篩選出多個匹配程度高的區域。

  • loc=np.where(array > 0.8) #loc包含array中所有大于0.8的元素索引的數組

np.where(condition) 是 NumPy 的一個函數,當條件為真時,返回滿足條件的元素的索引。

  • *zip(loc)
    • *loc 是解包操作,將 loc 中的多個數組拆開,作為單獨的參數傳遞給 zip
    • zip 將這些數組按元素一一配對,生成一個迭代器,每個元素是一個元組,表示一個坐標點。
x=list([[1,2,3,4,3],[23,4,2,4,2]])
print(list(zip(*x)))			#[(1, 23), (2, 4), (3, 2), (4, 4), (3, 2)]

霍夫變換

原圖:(后面代碼都是基于此圖執行的)
在這里插入圖片描述

標準霍夫變換

lines=cv2.HoughLines(image, rho, theta, threshold)

  • image:輸入圖像,通常為二值圖像,其中白點表示邊緣點,黑點為背景。
  • rho:r的精度,以像素為單位,表示霍夫空間中每一步的距離增量, 值越大,考慮越多的線。
  • theta:角度θ的精度,通常以弧度為單位,表示霍夫空間中每一步的角度增量。值越小,考慮越多的線。
  • threshold:累加數閾值,只有累積投票數超過這個閾值的候選直線才會被返回。

返回值:cv2.HoughLines 函數返回一個二維數組,每一行代表一條直線在霍夫空間中的參數 (rho, theta)

import cv2 as cv
import numpy as np#讀圖
img=cv.imread('E:\hqyj\code\opencv\images\\huofu.png')#灰度化
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)#二值化
_,binary = cv.threshold(gray,127,255,cv.THRESH_BINARY)#邊緣檢測
edges = cv.Canny(binary,30,70)#霍夫變換 返回的是[r,theta]
lines = cv.HoughLines(edges,0.8,np.pi/180,90)
print(lines)		#[[[25.6        1.5707964]]# [[21.6        1.5707964]]        # [[42.4        2.146755 ]]        # [[46.4        2.146755 ]]]for line in lines:r,theta = line[0]sin_theta = np.sin(theta)cos_theta = np.cos(theta)x1,x2 = 0,img.shape[1]y1 = int([r-x1*cos_theta]/sin_theta)y2 = int([r-x2*cos_theta]/sin_theta)cv.line(img,(x1,y1),(x2,y2),(0,0,255),1)cv.imshow('img',img)
cv.waitKey(0)
cv.destroyAllWindows()

在這里插入圖片描述

統計概率霍夫直線變換

lines=cv2.HoughLinesP(image, rho, theta, threshold, lines=None, minLineLength=0, maxLineGap=0)

  • image:輸入圖像,通常為二值圖像,其中白點表示邊緣點,黑點為背景。
  • rho:極徑分辨率,以像素為單位,表示極坐標系中的距離分辨率。
  • theta:極角分辨率,以弧度為單位,表示極坐標系中角度的分辨率。
  • threshold:閾值,用于過濾掉弱檢測結果,只有累計投票數超過這個閾值的直線才會被返回。
  • lines(可選):一個可初始化的輸出數組,用于存儲檢測到的直線參數。
  • minLineLength(可選):最短長度閾值,比這個長度短的線會被排除。
  • maxLineGap(可選):同一直線兩點之間的最大距離。當霍夫變換檢測到一系列接近直角的線段時,這些線段可能是同一直線的不同部分。maxLineGap參數指定了在考慮這些線段屬于同一直線時,它們之間最大可接受的像素間隔。

返回值lines:cv2.HoughLinesP 函數返回一個二維數組,每個元素是一個包含4個元素的數組,分別表示每條直線的起始點和結束點在圖像中的坐標(x1, y1, x2, y2)。

import cv2 as cv
import numpy as np#讀圖
img=cv.imread('E:\hqyj\code\opencv\images\\huofu.png')#灰度化
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)#二值化
_,binary = cv.threshold(gray,127,255,cv.THRESH_BINARY)#邊緣檢測
edges = cv.Canny(binary,30,70)
lines = cv.HoughLinesP(edges,0.8,np.pi/180,90,minLineLength=50,maxLineGap=20)
print(lines)for line in lines:x1,y1,x2,y2 = line[0]cv.line(img,(x1,y1),(x2,y2),(0,0,255),2)cv.imshow('img',img)
cv.waitKey(0)
cv.destroyAllWindows()

在這里插入圖片描述

霍夫圓變換

circles=cv2.HoughCircles(image, method, dp, minDist, param1, param2)

  • image:輸入圖像,通常是灰度圖像。

  • method:使用的霍夫變換方法:霍夫梯度法,可以是 cv2.HOUGH_GRADIENT,這是唯一在OpenCV中用于圓檢測的方法。

  • dp:累加器分辨率與輸入圖像分辨率之間的降采樣比率,用于加速運算但不影響準確性。設置為1表示霍夫梯度法中累加器圖像的分辨率與原圖一致

  • minDist:檢測到的圓心之間的最小允許距離,以像素為單位。在霍夫變換檢測圓的過程中,可能會檢測到許多潛在的圓心。minDist 參數就是為了過濾掉過于接近的圓檢測結果,避免檢測結果過于密集。當你設置一個較小的 minDist 值時,算法會嘗試找出盡可能多的圓,即使是彼此靠得很近的圓也可能都被檢測出來。相反,當你設置一個較大的 minDist 值時,算法會傾向于只檢測那些彼此間存在一定距離的獨立的圓。

  • param1param2:這兩個參數是在使用 cv2.HOUGH_GRADIENT 方法時的特定參數,分別為:

    • param1(可選):閾值1,決定邊緣強度的閾值。
    • param2:閾值2,控制圓心識別的精確度。較大的該值會使得檢測更嚴格的圓。param2 通常被稱為圓心累積概率的閾值。在使用霍夫梯度方法時,param2 設置的是累加器閾值,它決定了哪些候選圓點集合被認為是有效的圓。較高的 param2 值意味著對圓的檢測更嚴格,只有在累加器中積累了足夠高的響應值才認為是真實的圓;較低的 param2 值則會降低檢測的門檻,可能會檢測到更多潛在的圓,但也可能包含更多的誤檢結果。

返回值:cv2.HoughCircles 返回一個二維numpy數組,包含了所有滿足條件的圓的參數。

import cv2 as cv
import numpy as np#讀圖
img=cv.imread('E:\hqyj\code\opencv\images\\huofu.png')#灰度化
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)#二值化
_,binary = cv.threshold(gray,127,255,cv.THRESH_BINARY)#邊緣檢測
edges = cv.Canny(binary,30,70)#霍夫圓變換
circles = cv.HoughCircles(edges,cv.HOUGH_GRADIENT,1,20,param1=20,param2=20,minRadius=0,maxRadius=0)
print(circles)for circle in circles:# 獲取圓心和半徑x,y,r = circle[0]print(x,y,r)x,y,r = np.int_(np.round(x)),np.int_(np.round(y)),np.int_(np.round(r))print(x,y,r)cv.circle(img,(x,y),r,(0,255,255),2)cv.imshow('img',img)
cv.waitKey(0)
cv.destroyAllWindows()

在這里插入圖片描述

圖像亮度變換

亮度變換

對比度調整:圖像暗處像素強度變低,圖像亮處像素強度變高,從而拉大中間某個區域范圍的顯示精度。

亮度調整:圖像像素強度整體變高或者變低。
在這里插入圖片描述
上圖中,(a)把亮度調高,就是圖片中的所有像素值加上了一個固定值;(b)把亮度調低,就是圖片中的所有像素值減去了一個固定值;(c)增大像素對比度(白的地方更白,黑的地方更黑);(d)減小像素對比度(整幅圖都趨于一個顏色);

OpenCV調整圖像對比度和亮度時,公式為:g(i,j)=αf(i,j)+βg(i,j)=\alpha f(i,j)+\betag(i,j)=αf(i,j)+β。但是不能淺顯的講α\alphaα是控制對比度,β\betaβ是控制亮度的。

對比度:需要通過α、β\alpha、\betaαβ一起控制。

亮度:通過β\betaβ控制。

線性變換

使用 cv2.addWeighted() 函數,可以對圖像的像素值進行加權平均,進而改變圖像的整體亮度。亮度增益可以通過向每個像素值添加一個正值來實現。

cv2.addWeighted(src1, alpha, src2, beta, gamma)

  • src1:第一張輸入圖像,它將被賦予權重 alpha

  • alpha:第一個輸入圖像的權重。

  • src2:第二張輸入圖像,它將被賦予權重 beta

  • beta:第二個輸入圖像的權重。

  • gamma:一個標量,將被添加到權重求和的結果上,可用于調整總體亮度。

    計算公式為: dst = src1 * alpha + src2 * beta + gamma

import cv2 as cv#讀圖
cat = cv.imread('E:\hqyj\code\opencv\images\\cat1.png')#線性變換
dst = cv.addWeighted(cat,0.8,cat,0,100)
cv.imshow('dst',dst)
cv.imshow('cat',cat)cv.waitKey(0)
cv.destroyAllWindows()

直接像素值修改

如果只需要增加或減少固定的亮度值,可以直接遍歷圖像像素并對每個像素值進行加減操作。

使用的API:

numpy.clip(a, a_min, a_max)

用于對數組中的元素進行限定,將超出指定范圍的元素值截斷至指定的最小值和最大值之間

  • a:輸入數組。

  • a_min:指定的最小值,數組中所有小于 a_min 的元素將被替換為 a_min

  • a_max:指定的最大值,數組中所有大于 a_max 的元素將被替換為 a_max

  #讀圖
cat = cv.imread('E:\hqyj\code\opencv\images\\cat1.png')#創建窗口 用于顯示滑條
window_name = 'slide'
cv.namedWindow(window_name)
img = cv.imread('E:\hqyj\code\opencv\images\\cat1.png')def chage(p):x = p/256*511-255dst=np.uint8(np.clip(img+x,0,255))cv.imshow(window_name,dst)print(x)#創建滑動條
initial_value = 127
chage(initial_value)
cv.createTrackbar('add_p',window_name,initial_value,255,chage)cv.waitKey(0)
cv.destroyAllWindows()

形態學變換

import cv2 as cv
import numpy as np#讀圖
car = cv.imread('E:\hqyj\code\opencv\images\\circle.png')#二值化
_,car = cv.threshold(car,127,255,cv.THRESH_BINARY_INV)
cv.imshow('car',car)#定義核 n*n的一個小區域
kernel = np.ones((5,5),np.uint8)#腐蝕 用全1核覆蓋,碰到前景時核中有背景值,就變為背景(縮小前景)
erosion = cv.erode(car,kernel,iterations = 1)
cv.imshow('erosion',erosion)#膨脹 用全1核覆蓋,碰到背景時核中有前景值,就變為前景(擴大前景)
dilation = cv.dilate(car,kernel,iterations = 1)
cv.imshow('dilation',dilation)#開運算	先腐蝕后膨脹
#作用:分離物體,消除小區域。特點:消除噪點,去除小的干擾塊,而不影響原來的圖像
opening = cv.morphologyEx(car,cv.MORPH_OPEN,kernel)
cv.imshow('opening',opening)#閉運算	先膨脹后腐蝕
#作用:是消除/“閉合”物體里面的孔洞。特點:可以填充閉合區域
closing = cv.morphologyEx(car,cv.MORPH_CLOSE,kernel)
cv.imshow('closing',closing)#禮帽運算 原圖和開運算的差
tophat = cv.morphologyEx(car,cv.MORPH_TOPHAT,kernel)
cv.imshow('tophat',tophat)#黑帽運算 原圖和閉運算的差
blackhat = cv.morphologyEx(car,cv.MORPH_BLACKHAT,kernel)
cv.imshow('blackhat',blackhat)#形態學梯度 膨脹和腐蝕的差
gradient = cv.morphologyEx(car,cv.MORPH_GRADIENT,kernel)
cv.imshow('gradient',gradient)cv.imshow('closing',closing)
cv.waitKey(0)
cv.destroyAllWindows()

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

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

相關文章

常見的未授權訪問漏洞靶場-練習教程

一.Redis未授權訪問漏洞1.首先需要準備一個vps和vulhub靶場&#xff0c;然后進入目錄。命令:進入靶場目錄&#xff1a;cd /etc/vulhub-master/redis/4-unacc 啟動靶場&#xff1a;docker-compose up -d2.然后啟動我們kali,下載redis服務然后連接redis&#xff0c;并執行命令。…

EAP(基于事件的異步編程模式)

&#x1f4dc; 1. 核心思想 &#x1f4cc; 事件驅動解耦 異步操作通過事件通知結果&#xff0c;調用者無需阻塞線程&#xff0c;通過事件處理器響應操作完成、錯誤或取消。 &#x1f4cc; 線程池與UI線程協同 耗時操作在后臺線程池執行&#xff0c;完成后通過 SynchronizationC…

【三橋君】如何解決后端Agent和前端UI之間的交互問題?——解析AG-UI協議的神奇作用

?你好&#xff0c;我是 ?三橋君? &#x1f4cc;本文介紹&#x1f4cc; >> 一、引言 在智能體&#xff08;Agent&#xff09;領域&#xff0c;MCP、A2A、ANP等協議已經規范了Agent與工具、Agent與Agent之間的通信&#xff0c;但Agent與用戶之間的交互一直缺乏標準化。…

面試官:詳細說說Kafka rebalance 的策略以及具體過程

hello啊&#xff0c;各位觀眾姥爺們&#xff01;&#xff01;&#xff01;本baby今天又來報道了&#xff01;哈哈哈哈哈嗝&#x1f436; 程序員各種工具大全 Kafka 的 Rebalance&#xff08;再平衡&#xff09; 是消費者組&#xff08;Consumer Group&#xff09;在消費者數量…

C++入門自學Day2-- c++類與對象(初識)

一、面向對象和面向過程1、什么是面向過程&#xff08;Process-Oriented Programming, POP&#xff09;&#x1f4cc; 定義面向過程強調的是 過程&#xff08;過程函數&#xff09;&#xff0c;即&#xff1a;按照步驟&#xff08;流程&#xff09;組織代碼。程序結構 數據結構…

DAO組織智能合約開發:從理論到實踐

目錄 DAO組織智能合約開發:從理論到實踐 1. DAO概述:去中心化自治組織 2. DAO核心組件設計 2.1 架構設計 2.2 關鍵智能合約 3. 治理代幣實現 3.1 ERC20擴展合約 4. 提案管理系統實現 4.1 提案狀態機 4.2 提案合約實現 5. DAO核心合約實現 5.1 DAO合約架構 5.2 提案類型擴展 6…

Ubuntu系統完整配置教程

Ubuntu系統完整配置教程 目錄 配置鏡像源安裝網絡服務虛擬機中安裝CUDAPython開發環境配置Java開發環境配置 1. 配置鏡像源 1.1 備份原始源文件 sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup1.2 編輯源文件 sudo nano /etc/apt/sources.list1.3 各大鏡像源…

【mysql慢查詢】

mysql慢查詢慢查詢慢查詢日志配置慢查詢 慢查詢是指執行時間超過指定閾值的SQL語句。在MySQL中&#xff0c;默認情況下執行時間超過10秒的查詢會被認為是慢查詢&#xff0c;但這個閾值可以根據需要進行調整。 慢查詢日志配置 -- 查看當前慢查詢配置 SHOW VARIABLES LIKE slo…

django 按照外鍵排序

在Django中&#xff0c;使用外鍵&#xff08;ForeignKey&#xff09;進行排序是一種常見的需求&#xff0c;特別是在處理數據庫關系時&#xff0c;如用戶和訂單之間的關系&#xff08;一個用戶有多個訂單&#xff09;。下面是如何在使用Django ORM時進行基于外鍵的排序。 定義模…

JAVA_EIGHTEEN_特殊文件

目錄 Properties屬性文件 XML的作用和應用場景 日志技術 Properties屬性文件 約束&#xff1a;只能是鍵值對 鍵不能重復 文件后綴一般是.properties結尾的 是一個Map集合&#xff08;鍵值對集合&#xff09; 核心作用&#xff1a;Properties是用來代表屬性文件的&#…

第二十二節 MATLAB轉置向量、MATLAB追加向量

MATLAB中轉置操作能夠將一個行向量改變成一個列向量&#xff0c;反之亦然。MATLAB中轉置操作使用一個單引號&#xff08;&#xff09;來表示。詳細例子在MATLAB中建立一個腳本文件&#xff0c;輸入下述代碼&#xff1a;r [ 1 2 3 4 ]; tr r; v [1;2;3;4]; tv v; disp(tr); …

window顯示驅動開發—Direct3D 11 視頻設備驅動程序接口 (DDI)

這些設備驅動程序接口 (DDI) 是新的或針對Windows 8更新的&#xff1a;CalcPrivateCryptoSessionSizeCalcPrivateAuthenticatedChannelSizeCalcPrivateVideoDecoderOutputViewSizeCalcPrivateVideoDecoderSizeCalcPrivateVideoProcessorEnumSizeCalcPrivateVideoProcessorInput…

新手向:用AI破解數據質量難題

用AI破解數據質量難題&#xff1a;從零開始的完整指南數據質量的重要性及其影響數據質量是數據分析、機器學習和業務流程中不可忽視的核心問題。低質量數據會導致一系列嚴重后果&#xff1a;錯誤決策&#xff1a;基于不準確或缺失的數據可能導致管理層做出錯誤判斷。例如&#…

用 Python 獲取電腦電池電量的各種案例

更多內容請見: python3案例和總結-專欄介紹和目錄 文章目錄 方法一:使用 `psutil` 庫(跨平臺) 方法二:Windows 專用方法(使用 `win32api`) 方法三:macOS 專用方法 方法四:Linux 專用方法 方法五:跨平臺統一方法 Python 程序案例:檢測電池電量并在低于20%時關機 以下…

Linux->自定義shell

目錄 引入&#xff1a; 1&#xff1a;shell是什么&#xff1f; 2&#xff1a;命令行提示符是什么&#xff1f; 3&#xff1a;xshell是什么&#xff1f; 一&#xff1a;命令行提示符 二&#xff1a; 獲取用戶輸入 三&#xff1a;分割字符串 四&#xff1a;執行命令 五…

js中出現-8.881784197001252e-16這種(一個極其接近 0 的極小負數)的浮點數精度計數異常問題解決思路

你的代碼中出現 -8.881784197001252e-16&#xff08;一個極其接近 0 的極小負數&#xff09;的原因是 JavaScript 浮點數精度問題。具體來說&#xff0c;當你反復進行 加法 和 減法 時&#xff0c;由于浮點數在計算機中的存儲方式&#xff0c;可能會引入微小的誤差。一、問題情…

超詳細的 RustDesk 自建中繼節點教程

厭倦了商業遠程控制軟件的會員限制和功能閹割&#xff1f;渴望擁有一個自由掌控、安全可靠的遠程連接方案&#xff1f;開源軟件 RustDesk 正是你需要的答案&#xff01; 相信從事互聯網工作的你&#xff0c;一定對向日葵和ToDesk等商業遠程控制軟件并不陌生。然而&#xff0c;…

Spring Boot 2整合Druid的兩種方式

一、自定義整合Druid&#xff08;非Starter方式&#xff09;適用于需要完全手動控制配置的場景添加依賴&#xff08;pom.xml&#xff09;<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</ve…

鴻蒙Next-開發版本升級,API升級(例如API12升API16)

鴻蒙更新換代很快的&#xff0c;2025年1月&#xff0c;截至4月就有 DevEco Studio 5.0.2 Release 升級到 DevEco Studio 5.0.3 Release 升級到 DevEco Studio 5.0.4 Release&#xff0c;三次大版本更新。 作者也想在年前創建的項目中體驗一下新版本的特性&#xff0c;于是查看了…

樹莓派設置時區

查看當前時間 piraspberrypi-CM5:~ $ date Mon 28 Jul 09:22:38 BST 2025BST 指的是 British Summer Time&#xff0c;即英國夏令時&#xff08;UTC1&#xff09;。 所以這是英國&#xff08;倫敦等地&#xff09;在夏令時期間的本地時間&#xff0c;比標準的 UTC 時間快 1 小時…