人工智能——Opencv圖像色彩空間轉換、灰度實驗、圖像二值化處理、仿射變化

一、圖像色彩空間轉換

(一)顏色加法

? ? ? ? 1、直接相加

????????1、直接相加

????????2、調用cv.add()函數進行飽和操作????????

在OpenCV中進行顏色的加法,我們說圖像即數組,所以從數據類型來說我們可以直接用numpy的知識來進行直接相加,但是存在溢出錯誤。

因為如果直接numpy進行直接相加,會進行取模運算,對256取模,相加后超出的值會又從0開始向上,例如250+10最后的值是4,導致色彩失真

#如果直接numpy進行直接相加,會進行取模運算,對256取模,相加后超出的值會又從0開始向上,例如250+10最后的值是4
dst2=pig+cao
#舉例子
x=np.uint8([[250]])
y=np.uint8([[10]])
print(x+y)
print(cv.add(x,y))

?正常進行圖像顏色加法時,調用庫中的API:飽和操作cv.add(img1,img2)? ? ? ? 類型是np.uint8 0~255 例如250+10最后到255就飽和不加了

#飽和操作cv.add(img1,img2)    np.uint8 0~255 例如250+10最后只能到255到飽和
dst1=cv.add(pig,cao)

? ? ? ? 2、顏色加權加法:cv.addWeighted(img1,α,img2,β,,γ)

? ? ? ?α、β分別是img1和img2的權重參數

?????????γ是亮度調整值,

????????????????γ>0時,整體亮度增加

????????????????γ<0時,整體亮度降低

????????????????γ=0時,亮度不變

#顏色加權加法 cv.addWeighted(img1,α,img2,β,,γ)     其中γ是亮度調整值,γ>0時,整體亮度增加,γ<0時,整體亮度降低,γ=0時,亮度不變
dst3 =cv.addWeighted(pig,0.7,cao,0.3,0)

(二)色彩空間轉換

圖像的顏色表示有很多方式,除了RGB外,還有HCV,Gray(灰度)等。

????????HSV顏色空間使用色調(Hue)、飽和度(Saturation)和亮度(Value)三個參數來表示顏色,色調H表示顏色的種類,如紅色、綠色、藍色等;飽和度表示顏色的純度或強度,如紅色越純,飽和度就越高;亮度表示顏色的明暗程度,如黑色比白色亮度低

H: 0— 180

S: 0— 255

V: 0— 255

? ? ? ? Gray灰度圖像在進行二值化處理時需要使用,也經常需要對彩色圖像進行轉換

cv2.cvtColor:是OpenCV中的一個函數,用于圖像顏色空間的轉換。可以將一個圖像從一個顏色空間轉換為另一個顏色空間,比如從RGB到灰度圖,或者從RGB到HSV的轉換等

語法:cv2.cvtColor(img,code)

? ? ? ? img:輸入圖像

? ? ? ? code:指定轉換的類型,比如cv.COLOR_RGB2GRAY表示從rgb到灰度圖像的轉換

? ? ? ? cv.COLOR_RGB2HSV表示從GGB圖像轉換到HSV圖像

import cv2 as cv
#讀取圖像
img = cv.imread("../images/1.jpg")
cv.imshow("img",img)#顏色轉換cv.cvtcolor(img,code)  (得到的是一個新的圖像數組,所以是有返回值的)
#轉灰度
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
cv.imshow("gray",gray)
#轉HSV
hsv = cv.cvtColor(img,cv.COLOR_BGR2HSV)
cv.imshow("hsv",hsv)
#轉RGB
rgb = cv.cvtColor(img,cv.COLOR_BGR2RGB)
cv.imshow("rgb",rgb)cv.waitKey(0)
cv.destroyAllWindows()

二、灰度實驗

????????灰度圖與彩色圖最大的不同就是:彩色圖是由R、G、B三個通道組成,而灰度圖只有一個通道,也稱為單通道圖像,所以彩色圖轉成灰度圖的過程本質上就是將R、G、B三通道合并成一個通道的過程

(一)最大值法

對于彩色圖像的每個像素,它會從R、G、B三個通道的值中選出最大的一個,并將其作為灰度圖像中對應位置的像素值

創建的思路:

  1. 首先需要讀取一張圖片
  2. 然后創建一個和圖片一樣大小的全0的圖像用來存儲圖片中的像素值
  3. 通過依次遍歷行列,然后取到每個像素對應三通道的值,用max小函數取出來賦值給當前像素即可

代碼實現:

import cv2 as cv
import numpy as npimg = cv.imread('../images/pig.png')#創一個一樣大小的全0圖像
img1 = np.zeros((img.shape[0],img.shape[1]),dtype=np.uint8)#循環遍歷每一行,img[0,0,0]
for  i in range(img.shape[0]): # 遍歷行for j in range(img.shape[1]): # 遍歷列img1[i,j]=max(img[i,j,0],img[i,j,1],img[i,j,2]) # 取最大值cv.imshow('img1',img1)
cv.waitKey(0)
cv.destroyAllWindows()

(二)平均值法

對于彩色圖像的每個像素,它會將R、G、B三個通道的像素值全部加起來,然后再除以三,得到的平均值就是灰度圖像中對應位置的像素值

方法:

  1. 讀取一張圖片
  2. 創建一樣大的全0的圖像存放新的像素點
  3. 依次遍歷行列,然后取到每個像素對應三通道的值,加起來整除3(注意,此處取到的三通道的值都是uint8(無符號8為整數,數值范圍在0~255)直接這樣相加可能存中值溢出,所以我們需要先將讀取到的圖片轉為int類型后再進行相加)
  4. 最后再把計算得到的int類型的通道值轉為uint8

代碼實現:

import cv2 as cv
import numpy as npimg = cv.imread('../images/pig.png')#創一個一樣大小的全0圖像
img1 = np.zeros((img.shape[0],img.shape[1]),dtype=np.uint8)#循環遍歷每一行,img[0,0,0]
for  i in range(img.shape[0]): # 遍歷行for j in range(img.shape[1]): # 遍歷列#為什么要先轉換為int類型呢?因為圖像數組通常都是uint8(無符號 8 位整數)取值范圍是 0 - 255,# 三個數直接相加可能會溢出,所以需要轉為int有符號的整數避免溢出,再用np.uint8給轉回來#//3 整除3是因為我們的像素值的通道都是整數img1[i,j]=np.uint8((int(img[i,j,0])+int(img[i,j,1])+int(img[i,j,2]))//3)cv.imshow('img1',img1)
cv.waitKey(0)
cv.destroyAllWindows()

(三 )加權平均值法

對于彩色圖像的每個像素,它會按照一定的權重去乘以每個通道的像素值,并將其相加,得到最后的值就是灰度圖像中對應位置的像素值

權重可以自行設定,所使用的權重之和應該等于1,方法與平均值法相似只是多了

  1. 讀取一張圖片
  2. 創建一樣大的全0的圖像存放新的像素點
  3. 依次遍歷行列,然后取到每個像素對應三通道的值,加起來整除3(注意,此處和權重相乘后通常會出現小數,但像素值又只能為整數,系統會自動向下或向上取整,為了讓結果更準確,所以會用round()函數進行四舍五入)
  4. 最后再把計算得到的int類型的通道值轉為uint8

代碼實現:

import cv2 as cv
import numpy as npimg = cv.imread('../images/pig.png')#創一個一樣大小的全0圖像
img1 = np.zeros((img.shape[0],img.shape[1]),dtype=np.uint8)# 定義權重
wb,wg,wr = 0.114,0.587,0.299#循環遍歷每一行,img[0,0,0]
for  i in range(img.shape[0]): # 遍歷行for j in range(img.shape[1]): # 遍歷列#為什么要先轉換為int類型呢?因為圖像數組通常都是uint8(無符號 8 位整數)取值范圍是 0 - 255,# 三個數直接相加可能會溢出,所以需要轉為int有符號的整數避免溢出,再用np.uint8給轉回來#//3 整除3是因為我們的像素值的通道都是整數#round()四舍五入img1[i,j]=np.uint8(round(wb*img[i,j,0]+wg*img[i,j,1]+wr*img[i,j,2])//3)cv.imshow('img1',img1)
cv.waitKey(0)
cv.destroyAllWindows()

三、圖像二值化處理

二值圖像的二維矩陣僅由0、1兩個值構成,“0”代表黑色,“1”代白色(也就是255的值),其操作的圖像是必須是灰度圖

(一)全局閾值法

語法:_,binary = cv2.threshold(img,thresh,maxval,type)

  • img:輸入圖像,要進行二值化處理的灰度圖。

  • thresh:設定的閾值。當像素值大于(或小于,取決于閾值類型)thresh時,該像素被賦予的值。

  • type:閾值處理的類型,

    包括:
    • 閾值法:cv.threshold(img, thresh, max_value, cv.THRESH_BINARY)

    • 反閾值法:cv.threshold(img, thresh, max_value, cv.THRESH_BINARY_INV)

    • 截斷閾值法:cv.threshold(img, thresh, max_value, cv.THRESH_TRUNC)

    • 低閾值零處理法:cv.threshold(img, thresh, max_value, cv.THRESH_TOZERO)

    • 超閾值零處理法cv.threshold(img, thresh, max_value, cv.THRESH_TOZERO_INV)

    • OTSU閾值法:cv.threshold(img, thresh, max_value, cv.THRESH_OSTU)或cv.threshold(img, thresh, max_value, cv.THRESH_OSTU_INV)

  • 返回值:

    • 第一個值(通常用下劃線表示):計算出的閾值,若使用自適應閾值法,會根據算法自動計算出這個值。

    • 第二個值(binary):二值化后的圖像矩陣。與輸入圖像尺寸相同。

? ? ? ? 閾值法:通過設置一個閾值,將灰度圖中的每一個像素值與該閾值進行比較,小于等于閾值的像素就被設置為0(通常代表背景),大于閾值的像素就被設置為maxval(通常代表前景)

? ? ? ? 反閾值法:與閾值法相反。反閾值法是當灰度圖的像素值大于閾值時,該像素值將會變成0(黑),當灰度圖的像素值小于等于閾值時,該像素值將會變成maxval。

? ? ? ? 截斷閾值法:將灰度圖中的所有像素與閾值進行比較,像素值大于閾值的部分將會被修改為閾值,小于等于閾值的部分不變

????????低閾值零處理:字面意思,就是像素值小于等于閾值的部分被置為0,大于閾值的部分不變

????????超閾值零處理:將灰度圖中的每個像素與閾值進行比較,像素值大于閾值的部分置為0(也就是黑色),像素值小于等于閾值的部分不變。

? ? ? ? OSTU閾值法:OSTU閾值法?并不是一個有效的閾值類型,THRESH_OTSU 本身并不是一個獨立的閾值化方法,通常與 THRESH_BINARYTHRESH_BINARY_INV 結合使用 默認情況下它會與 `THRESH_BINARY` 結合使用。也就是說,當你僅指定了 `cv2.THRESH_OTSU`,實際上等同于同時指定了 `cv2.THRESH_BINARY + cv2.THRESH_OTSU`

????????OSTU 閾值法是一種基于圖像灰度直方圖統計特性的閾值確定方法,目的是將圖像分為前景和背景兩部分,使得分割后的兩類之間的差異最大,也就是讓類間方差最大,從而找到一個最佳的閾值來實現二值化

? ? ? ? 遍歷所有可能的閾值,將設當前閾值為t,遍歷t到最大像素值減1,分別計算每個t對應的類間方差,使得類間方差值最大的那個t值就是OSTU算法所確定的最佳閾值,將圖像中灰度值小于等于這個閾值的像素設置為?0(黑色,代表背景),大于這個閾值的像素設置為?255(白色,代表前景),就完成了基于 OSTU 閾值法的二值化處理。

代碼實現:

import cv2 as cvflower = cv.imread('../images/flower.png')
# 讀取灰色圖像
# flower1 = cv.imread('../images/flower.png',0)#h灰度化處理
flower1 = cv.cvtColor(flower,cv.COLOR_BGR2GRAY)
flower1 = cv.resize(flower1,(360,360))
cv.imshow('flower1',flower1)#二值化,閾值法
_,binary = cv.threshold(flower1,127,255,cv.THRESH_BINARY)
cv.imshow('binary',binary)# 反閾值法,為什么前面用下劃線,因為此處返回的值是thresh,本身就是我們傳的參數,所以沒必要接收,就可以用下劃線占位
_,binary_inv =  cv.threshold(flower1,127,255,cv.THRESH_BINARY_INV)
cv.imshow('binary_inv',binary_inv)#截斷閾值法
_,binary_trunc= cv.threshold(flower1,180,255,cv.THRESH_TRUNC)
cv.imshow('binary_trunc',binary_trunc)#低閾值0處理
_,binary_zero =cv.threshold(flower1,127,255,cv.THRESH_TOZERO)
cv.imshow('binary_zero',binary_zero)#超閾值0處理
_,binary_zero_inv =cv.threshold(flower1,127,255,cv.THRESH_TOZERO_INV)
cv.imshow('binary_zero_inv',binary_zero_inv)#OTSU閾值法 默認結合了cv.THRESH_BINARY  THRESH_BINARY=THRESH_BINARY+THRESH_OTSU
thresh1,otsu=cv.threshold(flower1,200,255,cv.THRESH_OTSU)
cv.imshow('otsu',otsu)
print(thresh1)
# otsu閾值結合反閾值法
thresh2,otsu_inv = cv.threshold(flower1,200,255,cv.THRESH_BINARY_INV+cv.THRESH_OTSU)
cv.imshow('otsu_inv',otsu_inv)
print(thresh2)#自適應二值化,小區域計算
#取均值
auto_mean =cv.adaptiveThreshold(flower1,255,cv.ADAPTIVE_THRESH_MEAN_C,cv.THRESH_BINARY,11,2)
cv.imshow('auto_mean',auto_mean)
#高斯加權法
auto_gauss =  cv.adaptiveThreshold(flower1,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,cv.THRESH_BINARY,11,2)
cv.imshow('auto_gauss',auto_gauss)#顯示效果
cv.waitKey(0)
cv.destroyAllWindows()

四、圖像翻轉和仿射變換

1、圖像的鏡像翻轉:

在OpenCV中,圖片的鏡像旋轉是以圖像的中心為原點進行鏡像翻轉的

- cv2.flip(img,flipcode)**

- 參數

? - img: 要翻轉的圖像
- flipcode: 指定翻轉類型的標志
- flipcode=0: 垂直翻轉,圖片像素點沿x軸翻轉
- flipcode>0: 水平翻轉,圖片像素點沿y軸翻轉
- flipcode<0: 水平垂直翻轉,水平翻轉和垂直翻轉的結合

import cv2 as cv
face= cv.imread('../images/face.png')
cv.imshow('face',face)
#翻轉鏡像旋轉,以圖像的中心為原點cv.flip(img,flipcode)
#flipcode=0:垂直翻轉 沿x軸上下翻轉
flip_0 = cv.flip(face,0)
cv.imshow('flip_0',flip_0)#flipcode>0:沿y軸水平翻轉(左右翻轉)
flip_1 = cv.flip(face,1)
cv.imshow('flip_1',flip_1)#flipcode<0:沿xy軸同時翻轉(垂直水平都翻轉)
flip_2 = cv.flip(face,-1)
cv.imshow('flip_2',flip_2)cv.waitKey(0)
cv.destroyAllWindows()

2、仿射變換:

仿射變換(Affine Transformation)是一種線性變換,保持了點之間的相對距離不變。

仿射變換的基本性質:

????????保持直線
保持平行
比例不變性
不保持角度和長度

常見的仿射變換類型:旋轉,平移,縮放,剪切

對于仿射變換,最重要的一步是獲得變換矩陣,通過變換矩陣是的目標點變換到預定位置

原理:

????????對于 2D 圖像,任意像素點的坐標可以表示為齊次坐標形式?(x, y, 1)(增加維度便于統一處理平移)。仿射變換矩陣?M?是一個?3×3?的矩陣實際使用中常簡化為?2×3,通過補全最后一行?[0,0,1]?變為齊次矩陣)

????????原像素點?(x, y)?經過矩陣?M?變換后,得到新像素點?(x', y'),計算公式為:

展開后

此處的思維是我們再思考的時候進行的正向思考,通過變換矩陣得到變換后的像素點對應的值。

????????實際在圖像變換中,,我們通常需要根據目標圖像的像素點?(x', y')?反推它在原圖像中的對應像素點?(x, y),這一過程稱為 “逆變換

????????當我們對圖像進行旋轉得到新圖像后,新圖像中某個像素?(x', y')?的顏色,實際上來自原圖像中某個像素?(x, y)?的顏色。為了準確填充新圖像的像素值,必須找到?(x', y')?對應的?(x, y)

????????此時,就需要通過仿射矩陣?M?的逆矩陣?M^{-1}?來實現反推,通過逆矩陣來求解原像素點

變換過程:

已知目標像素?(x', y'),通過逆矩陣?M^{-1}?求解原像素?(x, y)

展開后:其中(a', b', c', d', e', f')?是逆矩陣的元素

在 OpenCV 的?warpAffine?等變換函數中,內部會自動通過逆矩陣計算:

  1. 遍歷目標圖像的每個像素?(x', y')
  2. 用逆矩陣?M^{-1}?計算其在原圖像中的對應點?(x, y)
  3. 取原圖像?(x, y)?的像素值,賦給目標圖像的?(x', y')

仿射變換函數:

cv2.warpAffine(img,M,dsize)

img:輸入圖像。

M:2x3的變換矩陣,類型為np.float32。

-dsize:輸出圖像的尺寸,形式為(width,height)

在實際運用時,最主要的是得到變換矩陣

? ????????圖像旋轉:

首先利用cv2.getRotationMatrix2D()函數得到旋轉矩陣:

????????cv2.getRotationMatrix2D(center,angle,scale)

  • center:旋轉中心點的坐標,格式為`(x,y)`。
  • angle:旋轉角度,單位為度,正值表示逆時針旋轉負值表示順時針旋轉。
  • scale:縮放比例,若設為1,則不縮放。
  • 返回值:M,2x3的旋轉矩陣。
import cv2 as cv
#讀圖
cat = cv.imread("../images/1.jpg")#獲取旋轉矩陣 cv2.getRotationMatrix20(center,angle,scale)
M = cv.getRotationMatrix2D((200,300),30,1)
print(M)cat = cv.warpAffine(cat,M,(640,580))
cv.imshow("cat",cat)cv.waitKey(0)
cv.destroyAllWindows()

? ? ? ? 圖像平移:

移操作可以將圖像中的每個點沿著某個方向移動一定的距離

假設我們有一個點 P(x,y),希望將其沿x軸方向平移t_x個單位,沿y軸方向平移t_y個單位到新的位置P′(x′,y′),那么平移公式如下:

? ? ? ? ? ? ? ? ? x′=x+tx

? ? ? ? ? ? ? ? ? y′=y+ty

在矩陣形式下,該變換可以表示為:

import cv2 as cv
import numpy as np
#讀圖
cat = cv.imread("../images/1.jpg")#定義平移量
tx=80
ty=120#定義平移矩陣
M = np.float32([[1,0,tx],[0,1,ty]])#仿射變換的API
cat = cv.warpAffine(cat,M,(1000,1000))
cv.imshow("cat",cat)cv.waitKey(0)
cv.destroyAllWindows()

????????圖像縮放

假設要把圖像的寬高分別縮放為0.5和0.8,那么對應的縮放因子sx=0.5,sy=0.8。

點$P(x,y)$對應到新的位置P'(x',y'),縮放公式為:

? ?x′=s_x*x

? ? y′=s_y*y

? 在矩陣形式下,該變換可以表示為

import cv2 as cv
import numpy as np
#讀圖
cat = cv.imread("../images/1.jpg")#定義縮放因子
sx=0.8
sy=0.5#定義縮放矩陣,最后一列是平移量
M = np.float32([[sx,0,0],[0,sy,0]])#仿射變換的API
cat = cv.warpAffine(cat,M,(1000,1000))
cv.imshow("cat",cat)cv.waitKey(0)
cv.destroyAllWindows()

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

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

相關文章

【JToken】JToken == null 判斷無效的問題

if (innerNode null) {continue; }Debug.Log($"toNode type: {node["toNode"]?.GetType()}");發現這個JToken 無法正確的判斷 是否為 null&#xff0c;再排除邏輯問題后&#xff0c;我基本能確定的是 這個對象 不返回的不是真正的C# NULL 輸出類型后是 N…

C++基于libmodbus庫實現modbus TCP/RTU通信

今天看到了一個參考項目中用到了modbus庫&#xff0c;看著使用很是方便&#xff0c;于是記錄一下。后面有時間了或者用到了再詳細整理。 參考&#xff1a;基于libmodbus庫實現modbus TCP/RTU通信-CSDN博客 一、介紹 1.1庫文件包含 1.2最簡單的使用 本人在QT6.5下&#xff0…

【原創】微信小程序添加TDesign組件

前言 TDesign 是騰訊公司推出的一款UI界面庫,至于騰訊的實力嘛,也不用多說了。 官網:https://tdesign.tencent.com/ 源碼:https://github.com/Tencent/tdesign 目前處于活躍狀態,發文前5日,該庫仍在更新中… 遇到的問題 雖然騰訊為微信小程序開發提供了一個討論的論壇,…

Vue的路由模式的區別和原理

路由模式 Vue 的路由模式指的是 Vue Router 提供的 URL 處理方式&#xff0c;主要有兩種&#xff1a;Hash 模式和History 模式。 Hash模式 在 Vue Router 中&#xff0c;默認使用的是 hash 模式&#xff0c;即 mode: hash。如果想要使用 history 模式&#xff0c;可以設置 mode…

通過TPLink路由器進行用戶行為審計實戰

用戶行為審計是指對用戶在網絡平臺上的行為進行監控和記錄&#xff0c;以便對其行為進行分析和評估的過程。隨著互聯網的普及和發展&#xff0c;用戶行為審計在網絡安全和數據隱私保護方面起到了重要的作用。 用戶行為審計可以幫助發現和預防網絡安全威助。通過對用戶的行為進行…

MYSQL 第一次作業

新建產品庫mysql> CREATE DATABASE mydb6_product;使用產品庫mysql> USE mydb6_product;創建employess表mysql> CREATE TABLE employees (-> id INT PRIMARY KEY,-> name VARCHAR(50) NOT NULL,-> age INT,-> gender VARCHAR(10) NOT NULL DEFAULT unknow…

暑期前端訓練day7——有關vue-diff算法的思考

前言 今天分享一下我對vue的diff的探究&#xff0c;跟我一起深入底層&#xff0c;看一看vue是怎么進行diff的&#xff0c;它的復雜度如何&#xff0c;為什么性能這么高&#xff0c;diff的目標是盡可能的復用原來的真實dom&#xff0c;減少刪除真實dom和創建真實的dom的開銷&…

【Docker】Docker的初步認識以及Ubuntu下的Docker環境安裝、配置

前言 在當今快速迭代的軟件開發與部署領域&#xff0c;容器化技術已成為不可或缺的核心力量&#xff0c;而 Docker 作為容器化技術的杰出代表&#xff0c;正以其輕量、高效、可移植的特性深刻改變著開發與運維的模式。它有效解決了 “在我機器上能運行&#xff0c;在你那里卻不…

【密碼學】2. 古典密碼

目錄2. 古典密碼2.1 經典加密技術基礎2.2 代換技術2.2.1 算術密碼2.2.2 代換密碼&#xff08;Substitution Cipher&#xff09;2.3 置換技術2.4 乘積密碼2.5 歷史上的教訓2. 古典密碼 2.1 經典加密技術基礎 分類 代換&#xff08;Substitution&#xff09;&#xff1a;明文內…

CSS3文本陰影特效全攻略

CSS3文本陰影效果實現 下面我將創建一個展示各種CSS3文本陰影效果的頁面&#xff0c;包含多種樣式示例和代碼實現。 設計思路 創建具有視覺吸引力的標題區域提供多種文本陰影效果實例顯示對應的CSS代碼以供參考添加交互元素讓用戶自定義效果 實現代碼 <!DOCTYPE html&g…

JavaScript 03 嚴格檢查模式Strict字符串類型詳解

2.4 嚴格檢查模式Strict在 JavaScript 里&#xff0c;也是 有 “作用域” 這個說法的。 所以說&#xff0c;變量 也分 全局變量 和 局部變量。 當我們 直接 把 代碼 寫在 script 雙標簽里面的時候&#xff0c;我們 JS 會認為 這只是 一個 沒有名字的 函數&#xff01;&#xff…

車載診斷ECU架構

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 做到欲望極簡,了解自己的真實欲望,不受外在潮流的影響,不盲從,不跟風。把自己的精力全部用在自己。一是去掉多余,凡事找規律,基礎是誠信;二是…

使用vue-pdf-embed發現某些文件不顯示內容

在使用vue-pdf-embed過程中, 突然發現有些pdf文件可以正常打開, 有些文件只顯示了一些數字, 并且控制臺報出如下警告: Warning: loadFont - translateFont failed: “UnknownErrorException: Ensure that the cMapUrl and cMapPacked API parameters are provided.”. Warning…

【設計模式C#】狀態模式(用于解決解耦多種狀態之間的交互)

一種行為設計模式。特點是用類的方式去管理狀態。優點&#xff1a;對每個狀態進行了封裝&#xff0c;提高了代碼的可維護性&#xff1b;減少了條件判斷語句的使用&#xff0c;降低維護成本&#xff1b;易于擴展&#xff0c;每次新增狀態都無需大規模修改其他類&#xff0c;符合…

WebSocket數據通過splice保持現有DOM結構僅更新文本內容?【防閃爍】。

文章目錄 前言 一、DOM更新優化機制 ?1.虛擬DOM復用性 2.?響應式系統觸發 二、性能對比 三、WebSocket場景實踐 ?1.防閃爍原理 2.代碼實現示例 四、特殊注意事項 總結 前言 開發過程中渲染websocket返回的數據時&#xff0c;經常會遇到更新數據閃爍的問題&#xff0c;咱們可…

深入解析Hadoop的Block多副本同步機制與Pipeline復制

Hadoop分布式文件系統概述作為Hadoop生態的核心存儲組件&#xff0c;HDFS&#xff08;Hadoop Distributed File System&#xff09;的設計哲學源于Google File System論文&#xff0c;其架構專門針對大規模數據集處理場景進行了優化。在理解Block多副本同步機制之前&#xff0c…

洪水預報中的序列到序列模型及其可解釋性擴展

洪水預報中的序列到序列模型及其可解釋性擴展 前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家&#xff0c;覺得好請收藏。點擊跳轉到網站。 1. 引言 洪水預報是水文科學和災害管理中的重要課題&#xff…

UniApp 優化實踐:使用常量統一管理本地存儲 Key,提升可維護性

在 UniApp 項目開發中&#xff0c;隨著功能的增加&#xff0c;本地存儲&#xff08;如 uni.setStorageSync&#xff09;的使用頻率也會增加。如果直接在代碼中硬編碼 key 值&#xff0c;不僅容易出錯&#xff0c;也難以后期維護。本文將以“自定義導航欄適配狀態欄高度”為例&a…

計算機網絡:(八)網絡層(中)IP層轉發分組的過程與網際控制報文協議 ICMP

計算機網絡&#xff1a;&#xff08;八&#xff09;網絡層&#xff08;中&#xff09;IP層轉發分組的過程與網際控制報文協議 ICMP前言一、IP層轉發分組的過程第一步&#xff1a;接收數據包并解封裝第二步&#xff1a;提取目標 IP 地址第三步&#xff1a;查詢路由表第四步&…

Python爬蟲實戰:研究concurrent-futures庫相關技術

1. 引言 1.1 研究背景與意義 網絡爬蟲作為互聯網數據采集的重要工具,在信息檢索、輿情分析、學術研究等領域具有廣泛應用。隨著互聯網數據量的爆炸式增長,傳統單線程爬蟲的效率已難以滿足需求,并發爬蟲技術成為研究熱點。 1.2 相關工作 現有爬蟲框架如 Scrapy、Beautifu…