opencv 圖像的旋轉

圖像的旋轉

  • 1 單點旋轉
  • 2. 圖片旋轉(cv2.getRotationMatrix2D)
  • 3. 插值方法
    • 3.1 最近鄰插值(cv2.INTER_NEAREST)
    • 3.2 雙線性插值(cv2.INTER_LINEAR)
    • 3.3 像素區域插值(cv2.INTER_AREA)
    • 3.4 雙三次插值(cv2.INTER_CUBIC)
    • 3.5 Lanczos插值(cv2.INTER_LANCZOS4)
    • 3.6 小結
  • 4. 邊緣填充方式(cv2.warpAffine的屬性borderMode)
    • 4.1 邊界復制(BODER_REPLICATE)
      • 4.2 邊界反射(BORDER_REFLECT)
    • 4.3 邊界反射101(BORDER_REFLECT_101)
    • 4.4 邊界常數(BORDER_CONSTANT)
      • 4.5 邊界包裹(BORDER_WRAP)

圖像旋轉是指圖像以某一點為旋轉中心,將圖像中的所有像素點都圍繞該點旋轉一定的角度,并且旋轉后的像素點組成的圖像與原圖像相同。

1 單點旋轉

首先我們以最簡單的一個點的旋轉為例子,且以最簡單的情況舉例,令旋轉中心為坐標系中心O(0,0),假設有一點 P 0 ( x 0 , y 0 ) P_{0}(x_{0},y_{0}) P0?(x0?,y0?) P 0 P_{0} P0?離旋轉中心O的距離為r, O P 0 OP_{0} OP0?與坐標軸x軸的夾角為 α \alpha α P 0 P_{0} P0?繞O順時針旋轉 θ \theta θ角后對應的點為 P ( x , y ) P(x,y) P(x,y),如下圖所示:

在這里插入圖片描述
單點旋轉的原理

2. 圖片旋轉(cv2.getRotationMatrix2D)

明白了單個點的旋轉過程之后,其實圖像旋轉也很好理解,就是將圖像里的每個像素點都帶入仿射變換矩陣里,從而得到旋轉后的新坐標。在OpenCV中,要得到仿射變換矩陣可以使用cv2.getRotationMatrix2D(),通過這個函數即可直接獲取到上面的旋轉矩陣,
格式如下:

cv2.RotationMatrix2D(Center,Angle,Scale)

該函數需要接收的參數為:

  • Center:表示旋轉的中心點,是一個二維的坐標點(x,y)
  • Angle:表示旋轉的角度
  • Scale:表示縮放比例,可以通過該參數調整圖像相對于原始圖像的大小變化

因此,在本實驗中只需要在組件中填好圖片要旋轉的角度與縮放的比例即可。
在這里插入圖片描述
代碼如下:

 '''圖片的旋轉'''img=cv2.imread(r"../15day4.10/src/1.jpg")# 求出圖片的高寬和顏色h,w,c=img.shape# 給出一個旋轉角度angle=45# 給出縮放倍數sacle=1# 以圖片的中心作為旋轉中心的仿射變換矩陣m=cv2.getRotationMatrix2D((h/2,w/2),angle=angle,scale=sacle)img_rotate=cv2.warpAffine(img,m,(w,h))cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)

在這里插入圖片描述

但是這里會有一個問題:

  • 由于三角函數的值是小數,那么其乘積也會是小數,雖然OpenCV中會對其進行取整操作,但是像素點旋轉之后的取整結果也有可能重合,這樣就會導致可能會在旋轉的過程中丟失一部分原始的像素信息。
  • 并且如果使用了scale參數進行圖像的縮放的話,當圖像放大時,比如一個10*10的圖像放大成20*20,圖像由100個像素點變成400個像素點,那么多余的300個像素點是怎么來的?而當圖像縮小時,比如一個20*20的圖像縮小為10*10的圖像,需要丟掉300個像素點,那到底要怎么丟才能保證圖像還能是一個正常的圖像?
  • 因此我們需要一種方法來幫我們計算旋轉后的圖像中每一個像素點所對應的像素值,從而保證圖像的完整性,這種方法就叫做插值法。

3. 插值方法

在圖像處理和計算機圖形學中,插值(Interpolation)是一種通過已知數據點之間的推斷或估計來獲取新數據點的方法。它在圖像處理中常用于處理圖像的放大、縮小、旋轉、變形等操作,以及處理圖像中的像素值。

圖像插值算法是為了解決圖像縮放或者旋轉等操作時,由于像素之間的間隔不一致而導致的信息丟失和圖像質量下降的問題。當我們對圖像進行縮放或旋轉等操作時,需要在新的像素位置上計算出對應的像素值,而插值算法的作用就是根據已知的像素值來推測未知位置的像素值。本實驗提供了五種常見的插值算法,下面一一介紹。

3.1 最近鄰插值(cv2.INTER_NEAREST)

最近鄰插值的原理
代碼如下:

'''最近鄰插值法'''img=cv2.imread(r"../15day4.10/src/1.jpg")# 求出圖片的高寬和顏色h,w,c=img.shape# 給出一個旋轉角度angle=45# 給出縮放倍數sacle=1.5#給出縮放后的圖像的窗口大小frame=(2*w,2*h)# 以圖片的中心作為旋轉中心的仿射變換矩陣m=cv2.getRotationMatrix2D((h/2,w/2),0,sacle)img_rotate=cv2.warpAffine(img,m,frame,flags=cv2.INTER_NEAREST)cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)

在這里插入圖片描述

3.2 雙線性插值(cv2.INTER_LINEAR)

雙線性插值的原理
代碼如下:

 '''雙線性插值'''img=cv2.imread(r"../15day4.10/src/1.jpg")# 求出圖片的高寬和顏色h,w,c=img.shape# 給出一個旋轉角度angle=45# 給出縮放倍數sacle=1.5#給出縮放后的圖像的窗口大小frame=(2*w,2*h)# 以圖片的中心作為旋轉中心的仿射變換矩陣m=cv2.getRotationMatrix2D((h/2,w/2),0,sacle)img_rotate=cv2.warpAffine(img,m,frame,flags=cv2.INTER_LINEAR)cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)

在這里插入圖片描述
注意:

  • 雙線性插值和最近鄰插值的區別就,當放大倍數為小數時,最近鄰插值(cv2.INTER_NEAREST)是對結果下取整,而雙線性插值(cv2.INTER_LINEAR)根據距離哪個像素點近就將取大的權值
  • 在這里插入圖片描述

3.3 像素區域插值(cv2.INTER_AREA)

像素區域插值主要分兩種情況,縮小圖像和放大圖像的工作原理并不相同。

當使用像素區域插值方法進行縮小圖像時,它就會變成一個均值濾波器(濾波器其實就是一個核,這里只做簡單了解,后面實驗中會介紹),其工作原理可以理解為對一個區域內(均值濾波器/核)的像素值取平均值。

當使用像素區域插值方法進行放大圖像時,如果圖像放大的比例是整數倍,那么其工作原理與最近鄰插值類似;如果放大的比例不是整數倍,那么就會調用雙線性插值進行放大。

其中目標像素點與原圖像的像素點的對應公式如下所示:
s r c X = d s t X ? s r c W i d t h d s t W i d t h s r c X=d s t X*{\frac{s r c W i d t h}{d s t W i d t h}} srcX=dstX?dstWidthsrcWidth?

s r c Y = d s t Y ? s r c H e i g h t d s t H e i g h t s r c Y=d s t Y*{\frac{s r c H e i g h t}{d s t H e i g h t}} srcY=dstY?dstHeightsrcHeight?
代碼如下:

 '''像素區域插值'''img=cv2.imread(r"../15day4.10/src/1.jpg")# 求出圖片的高寬和顏色h,w,c=img.shape# 給出一個旋轉角度angle=45# 給出縮放倍數sacle=1.5#給出縮放后的圖像的窗口大小frame=(2*w,2*h)# 以圖片的中心作為旋轉中心的仿射變換矩陣m=cv2.getRotationMatrix2D((h/2,w/2),0,sacle)img_rotate=cv2.warpAffine(img,m,frame,flags=cv2.INTER_AREA)cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)      


像素區域插值(cv2.INTER_AREA)就是最近鄰插值和雙線性插值的結合

3.4 雙三次插值(cv2.INTER_CUBIC)

與雙線性插值法相同,該方法也是通過映射,在映射點的鄰域內通過加權來得到放大圖像中的像素值。不同的是,雙三次插值法需要原圖像中近鄰的16個點來加權。

目標像素點與原圖像的像素點的對應公式如下所示:
s r c X = d s t X ? s r c W i d t h d s t W i d t h s r c X=d s t X*{\frac{s r c W i d t h}{d s t W i d t h}} srcX=dstX?dstWidthsrcWidth?

s r c Y = d s t Y ? s r c H e i g h t d s t H e i g h t s r c Y=d s t Y*{\frac{s r c H e i g h t}{d s t H e i g h t}} srcY=dstY?dstHeightsrcHeight?

下面我們舉例說明,假設原圖像A大小為m*n,縮放后的目標圖像B的大小為M*N。其中A的每一個像素點是已知的,B是未知的,我們想要求出目標圖像B中每一個像素點(X,Y)的值,必須先找出像素(X,Y)在原圖像A中對應的像素(x,y),再根據原圖像A距離像素(x,y)最近的16個像素點作為計算目標圖像B(X,Y)處像素值的參數,利用BiCubic基函數求出16個像素點的權重,圖B像素(x,y)的值就等于16個像素點的加權疊加。

假如下圖中的P點就是目標圖像B在(X,Y)處根據上述公式計算出的對應于原圖像A中的位置,P的坐標位置會出現小數部分,所以我們假設P點的坐標為(x+u,y+v),其中x、y表示整數部分,u、v表示小數部分,那么我們就可以得到其周圍的最近的16個像素的位置,我們用a(i,j)(i,j=0,1,2,3)來表示,如下圖所示。

在這里插入圖片描述

然后給出BiCubic函數:
JYBx-1745050039632)

其中,a一般取-0.5或-0.75。

我們要做的就是將上面的16個點的坐標帶入函數中,獲取16像素所對應的權重 W ( x ) W(x) W(x)。然而BiCubic函數是一維的,所以我們需要將像素點的行與列分開計算,比如a00這個點,我們需要將x=0帶入BiCubic函數中,計算a00點對于P點的x方向的權重,然后將y=0帶入BiCubic函數中,計算a00點對于P點的y方向的權重,其他像素點也是這樣的計算過程,最終我們就可以得到P所對應的目標圖像B在(X,Y)處的像素值為:
B ( X , Y ) = ∑ i = 0 3 ∑ j = 0 3 a i j × W ( i ) × W ( j ) B(X,Y)=\sum_{i=0}^{3}\sum_{j=0}^{3}a_{i j}\times W_{(i)}\times W_{(j)} B(X,Y)=i=03?j=03?aij?×W(i)?×W(j)?
依此辦法我們就可以得到目標圖像中所有的像素點的像素值。

代碼如下:

'''雙三次插值'''img=cv2.imread(r"../15day4.10/src/1.jpg")# 求出圖片的高寬和顏色h,w,c=img.shape# 給出一個旋轉角度angle=45# 給出縮放倍數sacle=1.5#給出縮放后的圖像的窗口大小frame=(2*w,2*h)# 以圖片的中心作為旋轉中心的仿射變換矩陣m=cv2.getRotationMatrix2D((h/2,w/2),0,sacle)img_rotate=cv2.warpAffine(img,m,frame,flags=cv2.INTER_CUBIC)cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)      

在這里插入圖片描述
雙三次插值(cv2.INTER_CUBIC)比雙線性插值(cv2.INTER_LINEAR)對圖片處理更精細,但是執行效率比較低

3.5 Lanczos插值(cv2.INTER_LANCZOS4)

Lanczos插值方法與雙三次插值的思想是一樣的,不同的就是其需要的原圖像周圍的像素點的范圍變成了8*8,并且不再使用BiCubic函數來計算權重,而是換了一個公式計算權重。

首先還是目標像素點與原圖像的像素點的對應公式如下所示:
s r c X = d s t X ? s r c W i d t h d s t W i d t h s r c X=d s t X*{\frac{s r c W i d t h}{d s t W i d t h}} srcX=dstX?dstWidthsrcWidth?

s r c Y = d s t Y ? s r c H e i g h t d s t H e i g h t s r c Y=d s t Y*{\frac{s r c H e i g h t}{d s t H e i g h t}} srcY=dstY?dstHeightsrcHeight?

下面我們舉例說明,假設原圖像A大小為m*n,縮放后的目標圖像B的大小為M*N。其中A的每一個像素點是已知的,B是未知的,我們想要求出目標圖像B中每一個像素點(X,Y)的值,必須先找出像素(X,Y)在原圖像A中對應的像素(x,y),再根據原圖像A距離像素(x,y)最近的64個像素點作為計算目標圖像B(X,Y)處像素值的參數,利用權重函數求出64個像素點的權重,圖B像素(x,y)的值就等于64個像素點的加權疊加。

假如下圖中的P點就是目標圖像B在(X,Y)處根據上述公式計算出的對應于原圖像A中的位置,P的坐標位置會出現小數部分,所以我們假設P點的坐標為(x+u,y+v),其中x、y表示整數部分,u、v表示小數部分,那么我們就可以得到其周圍的最近的64個像素的位置,我們用a(i,j)(i,j=0,1,2,3,4,5,6,7)來表示,如下圖所示。

在這里插入圖片描述

然后給出權重公式:
在這里插入圖片描述

其中a通常取2或者3,當a=2時,該算法適用于圖像縮小。a=3時,該算法適用于圖像放大。

與雙三次插值一樣,這里也需要將像素點分行和列分別帶入計算權重值,其他像素點也是這樣的計算過程,最終我們就可以得到P所對應的目標圖像B在(X,Y)處的像素值為:
S ( x , y ) = ∑ i = [ x ] ? a + 1 [ x ] + a ∑ j = [ y ] ? a + 1 [ y ] + a s i j L ( x ? i ) L ( y ? j ) S(x,y)=\sum_{i=[x]-a+1}^{[x]+a}\sum_{j=[y]-a+1}^{[y]+a}s_{i j}L(x-i)L(y-j) S(x,y)=i=[x]?a+1[x]+a?j=[y]?a+1[y]+a?sij?L(x?i)L(y?j)
其中 [ x ] [x] [x] [ y ] [y] [y]表示對坐標值向下取整,通過該方法就可以計算出新的圖像中所有的像素點的像素值。
代碼如下:

 '''lanczos'''img=cv2.imread(r"../15day4.10/src/1.jpg")# 求出圖片的高寬和顏色h,w,c=img.shape# 給出一個旋轉角度angle=45# 給出縮放倍數sacle=1.5#給出縮放后的圖像的窗口大小frame=(2*w,2*h)# 以圖片的中心作為旋轉中心的仿射變換矩陣m=cv2.getRotationMatrix2D((h/2,w/2),0,sacle)img_rotate=cv2.warpAffine(img,m,frame,flags=cv2.INTER_LANCZOS4)cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)      

在這里插入圖片描述

3.6 小結

最近鄰插值的計算速度最快,但是可能會導致圖像出現鋸齒狀邊緣和失真,效果較差。雙線性插值的計算速度慢一點,但效果有了大幅度的提高,適用于大多數場景。雙三次插值、Lanczos插值的計算速度都很慢,但是效果都很好。

在OpenCV中,關于插值方法默認選擇的都是雙線性插值,且一般情況下雙線性插值已經能滿足大部分需求。

4. 邊緣填充方式(cv2.warpAffine的屬性borderMode)

在這里插入圖片描述

可以看到,左圖在逆時針旋轉45度之后原圖的四個頂點在右圖中已經看不到了,同時,右圖的四個頂點區域其實是什么都沒有的,因此我們需要對空出來的區域進行一個填充。右圖就是對空出來的區域進行了像素值為(0,0,0)的填充,也就是黑色像素值的填充。除此之外,后續的一些圖像處理方式也會用到邊緣填充,這里介紹五個常用的邊緣填充方法。

4.1 邊界復制(BODER_REPLICATE)

邊界復制會將邊界處的像素值進行復制,然后作為邊界填充的像素值,如下圖所示,可以看到四周的像素值都一樣。
在這里插入圖片描述
代碼如下:

 '''邊界復制'''img=cv2.imread(r"../15day4.10/src/face.png")# 求出圖片的高寬和顏色h,w,c=img.shape# 給出一個旋轉角度angle=45# 給出縮放倍數sacle=1#給出縮放后的圖像的窗口大小frame=(2*w,2*h)# 以圖片的中心作為旋轉中心的仿射變換矩陣m=cv2.getRotationMatrix2D((h/2,w/2),angle,sacle)img_rotate=cv2.warpAffine(img,m,frame,borderMode=cv2.BORDER_REPLICATE)cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)      

在這里插入圖片描述

4.2 邊界反射(BORDER_REFLECT)

如下圖所示,會根據原圖的邊緣進行反射。
在這里插入圖片描述

代碼如下:

 '''邊界反射'''img=cv2.imread(r"../15day4.10/src/face.png")# 求出圖片的高寬和顏色h,w,c=img.shape# 給出一個旋轉角度angle=45# 給出縮放倍數sacle=1#給出縮放后的圖像的窗口大小frame=(2*w,2*h)# 以圖片的中心作為旋轉中心的仿射變換矩陣m=cv2.getRotationMatrix2D((h/2,w/2),angle,sacle)img_rotate=cv2.warpAffine(img,m,frame,borderMode=cv2.BORDER_REFLECT)cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)    

在這里插入圖片描述
邊界反射是將原圖沿著原圖的邊界鏡像復制填充整個邊框

4.3 邊界反射101(BORDER_REFLECT_101)

與邊界反射不同的是,不再反射邊緣的像素點,如下圖所示。
在這里插入圖片描述
代碼如下:

 '''邊界反射_101'''img=cv2.imread(r"../15day4.10/src/face.png")# 求出圖片的高寬和顏色h,w,c=img.shape# 給出一個旋轉角度angle=45# 給出縮放倍數sacle=1#給出縮放后的圖像的窗口大小frame=(2*w,2*h)# 以圖片的中心作為旋轉中心的仿射變換矩陣m=cv2.getRotationMatrix2D((h/2,w/2),angle,sacle)img_rotate=cv2.warpAffine(img,m,frame,borderMode=cv2.BORDER_REFLECT_101)cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)

在這里插入圖片描述
邊界反射101是將原圖以原圖的邊界為軸鏡像復制填充整個邊框

4.4 邊界常數(BORDER_CONSTANT)

當選擇邊界常數時,還要指定常數值是多少,默認的填充常數值為0,如下圖所示。

img2=cv2.warpAffine(img,M,(shape[1],shape[0]),flags=cv2.INTER_LINEAR,borderMode=cv2.BORDER_CONSTANT,borderValue=100)


代碼如下:

'''邊界常數'''img=cv2.imread(r"../15day4.10/src/face.png")# 求出圖片的高寬和顏色h,w,c=img.shape# 給出一個旋轉角度angle=45# 給出縮放倍數sacle=1#給出縮放后的圖像的窗口大小frame=(2*w,2*h)# 以圖片的中心作為旋轉中心的仿射變換矩陣m=cv2.getRotationMatrix2D((h/2,w/2),angle,sacle)#邊界常數(borderMode=cv2.BORDER_CONSTANT)的邊界值(borderVlue)為0則是黑色,如果就是一個值的話是將bgr這三個值都賦值為這個值img_rotate=cv2.warpAffine(img,m,frame,borderMode=cv2.BORDER_CONSTANT,borderValue=(0,0,255))cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)

在這里插入圖片描述
邊界常數(borderMode=cv2.BORDER_CONSTANT)的邊界值(borderVlue)為0則是黑色,如果就是一個值的話是將bgr這三個值都賦值為這個值

4.5 邊界包裹(BORDER_WRAP)

如下圖所示。
在這里插入圖片描述
代碼如下:

'''邊界包裹'''img=cv2.imread(r"../15day4.10/src/face.png")# 求出圖片的高寬和顏色h,w,c=img.shape# 給出一個旋轉角度angle=45# 給出縮放倍數sacle=1#給出縮放后的圖像的窗口大小frame=(2*w,2*h)# 以圖片的中心作為旋轉中心的仿射變換矩陣m=cv2.getRotationMatrix2D((h/2,w/2),angle,sacle)img_rotate=cv2.warpAffine(img,m,frame,borderMode=cv2.BORDER_WRAP)cv2.imshow("img",img)cv2.imshow("img_rotate",img_rotate)cv2.waitKey(0)

在這里插入圖片描述
邊界包裹(cv2.BORDER_WRAP)的含義就是將圖片平鋪填充窗口

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

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

相關文章

如何在 Odoo 18 中配置自動化動作

如何在 Odoo 18 中配置自動化動作 Odoo是一款多功能的業務管理平臺,旨在幫助各種規模的企業更高效地處理日常運營。憑借其涵蓋銷售、庫存、客戶關系管理(CRM)、會計和人力資源等領域的多樣化模塊,Odoo 簡化了業務流程&#xff0c…

每日兩道leetcode

345. 反轉字符串中的元音字母 - 力扣(LeetCode) 題目 給你一個字符串 s ,僅反轉字符串中的所有元音字母,并返回結果字符串。 元音字母包括 a、e、i、o、u,且可能以大小寫兩種形式出現不止一次。 示例 1:…

【SQL 基礎入門 1. -- SQL 基本語法詳解及舉例】

文章目錄 SQL 數據庫創建及使用刪除數據庫SQL 查看數據空中有哪些表格SQL 創建表格SQL 修改表格列數據格式SQL 表格插入數據SQL 查看表格類型組成SQL 查看表格中的內容 SQL 查詢語句SQL 查看指定列SQL 選擇指定列SQL 按指定列進行升序排序SQL 平均值/求和/最大值/最小值 SQL 數…

PostgreSQL 分區表——范圍分區SQL實踐

PostgreSQL 分區表——范圍分區SQL實踐 1、環境準備1-1、新增原始表1-2、執行腳本新增2400w行1-3、創建pg分區表-分區鍵為創建時間1-4、創建24年所有分區1-5、設置默認分區(兜底用)1-6、遷移數據1-7、創建分區表索引 2、SQL增刪改查測試2-1、查詢速度對比…

Apache Flink 深度解析:流處理引擎的核心原理與生產實踐指南

Apache Flink 深度解析:流處理引擎的核心原理與生產實踐指南 引言:實時計算的范式革命 2023年雙十一期間,某頭部電商平臺基于Flink構建的實時風控系統成功攔截了每秒超過120萬次的異常交易請求。這背后是Apache Flink作為第四代計算引擎的強…

【Java學習筆記】選擇結構

選擇結構 內容結構 一、順序結構 二、分支控制 (1)單分支 (2)雙分支 (3)多分支 (4)嵌套分支 (5)switch 分支結構 三、switch和if的比較 一、順序結構…

03_JavaScript

文章目錄 一、概述1.1、JavaScript簡介1.2、JavaScript組成部分1.3、為什么要學習JavaScript1.4、學習的目的1.5、JavaScript與Java的關系 二、使用位置及運行說明2.1、使用位置2.2、如何運行 三、JavaScript基礎語法3.1、變量3.2、運算符3.3、控制流程3.3.1、分支結構3.3.2、循…

PySide6 GUI 學習筆記——常用類及控件使用方法(常用類矩陣QRect)

文章目錄 一、構造與初始化方法二、坐標與尺寸獲取三、坐標與尺寸設置四、幾何運算方法五、移動與調整方法六、狀態判斷方法七、類型轉換方法八、操作符重載九、靜態方法十、特殊方法附錄方法速查表注意的問題交集和并集圖解 📘 PySide6.QtCore.QRect 使用整數精度定…

AI 開發入門之 RAG 技術

目錄 一、從一個簡單的問題開始二、語言模型“閉卷考試”的困境三、RAG 是什么—LLM 的現實世界“外掛”四、RAG 的七步流程第一步:加載數據(Load)第二步:切分文本(Chunking)第三步:向量化&…

解決yarn install 報錯 error \node_modules\electron: Command failed.

在電腦重裝系統后,重新安裝項目依賴,遇到這一報錯 完整報錯信息如下: error D:\xxxxx\xxxxxx\node_modules\electron: Command failed. Exit code: 1 Command: node install.js Arguments: Directory: D:\xxxxx\xxxxx\node_modules\electron Output: HTTPError: Response cod…

2025年3月電子學會青少年機器人技術(五級)等級考試試卷-理論綜合

青少年機器人技術等級考試理論綜合試卷(五級) 分數:100 題數:30 一、單選題(共20題,共80分) 1. 2025年初,中國科技初創公司深度求索在大模型領域迅速崛起,其開源的大模型成為全球AI領域的焦…

23種設計模式-行為型模式之模版方法模式(Java版本)

Java 模板方法模式(Template Method Pattern)詳解 🧠 什么是模板方法模式? 模板方法模式是一種行為型設計模式,在一個方法中定義一個操作中的算法骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在…

長城杯鐵人三項初賽-REVERSE復現

前言 記錄記錄 1.LoginToMe int __fastcall main(int argc, const char **argv, const char **envp) {unsigned int v3; // eaxchar s[96]; // [rsp10h] [rbp-70h] BYREFint v6; // [rsp70h] [rbp-10h]int v7; // [rsp78h] [rbp-8h]int i; // [rsp7Ch] [rbp-4h]memset(s, 0, s…

DNS實驗

DNS原理 客戶端發起請求:客戶端向本地 DNS 服務器發送域名解析請求,這是流程的起始點。本地 DNS 服務器查詢根域名服務器:若本地 DNS 服務器緩存中無對應記錄,它向根域名服務器發起查詢,根域名服務器是 DNS 系統頂層&a…

SQLMesh 通知系統深度解析:構建自動化監控體系

SQLMesh 是一款強大的數據編排工具,其內置的靈活通知系統可顯著提升團隊協作效率。本文將系統解讀 SQLMesh 的通知機制,涵蓋配置方法、事件觸發邏輯及高級定制技巧。 一、通知系統的核心架構 1. 通知目標(Notification Targets) …

精益數據分析(20/126):解析經典數據分析框架,助力創業增長

精益數據分析(20/126):解析經典數據分析框架,助力創業增長 在創業和數據分析的學習道路上,每一次深入探索都可能為我們帶來新的啟發。今天,依舊帶著和大家共同進步的想法,我們一起深入研讀《精…

【OSG學習筆記】Day 8: 紋理貼圖——賦予模型細節

在 OSG(Open Scene Graph)中,紋理貼圖是為模型添加細節的關鍵技術,主要涉及紋理加載、UV 映射和多重紋理疊加三部分。 基礎理論 紋理加載 紋理的作用,就是將2D圖像映射到3D模型表面,增強視覺細節。 紋理類型與格式支持: OSG 支持多種圖像格式,包括常見的 .jpg/.jpe…

基于事件驅動的云原生后端架構設計:從理念到落地

??個人主頁??:慌ZHANG-CSDN博客 ????期待您的關注 ???? 一、引言:微服務之后,事件驅動正在成為新范式 隨著業務復雜度的提升,傳統同步式微服務調用模式逐漸暴露出瓶頸:服務間耦合度高、并發能力有限、出錯鏈路復雜。而在互聯網業務、金融交易、物聯網等場景中…

vue3:十一、主頁面布局(修改頂部導航欄樣式-右側:用戶信息+退出登錄+全屏顯示)

一、效果 完成效果,增加頂部導航欄,右側用戶信息(其中個人中心需要后續進行頁面開發,這里只寫了退出登錄功能),以及全屏功能 二、搭建并引入右側組件 將右側內容封裝到單獨的組件,直接引入(像左側導航條等內容也是可以做成這種形式) 1、新建右側組件的頁面 在layout中…

沁恒CHV203中斷嵌套導致修改線程棧-韋東山

調試專題bug實例 2025年01月09日20點場 處理辦法1:就是關閉中斷嵌套 處理辦法2: 使用原來的棧