OpenCV——直方圖與匹配

直方圖與匹配

  • 一、直方圖簡介
  • 二、直方圖統計
  • 三、直方圖比較
  • 四、直方圖均衡化
  • 五、自適應的直方圖均衡化
  • 六、直方圖反向投影
  • 七、模板匹配

一、直方圖簡介

圖像直方圖(Histogram)是一種頻率分布圖,它描述了不同強度值在圖像中出現的頻率。圖像直方圖可以統計任何圖像特征,如灰度、飽和度、梯度等。

彩色圖像的亮度直方圖就是其灰度圖的直方圖。亮度直方圖考慮了所有顏色通道,但有時也需要對單種顏色通道進行觀察分析。計算單種顏色通道直方圖時,每種顏色通道都作為一個獨立的灰度圖像,分別計算其直方圖。各種顏色通道的直方圖有時近似的,有時則相差甚遠,特別是當圖像偏于某一色系時。

在討論直方圖時經常涉及以下3個概念:

  1. Dims(維數):需要統計的特征的維數,一般情況下,圖像直方圖統計的特征只有一種,即灰度,此時的維數等于1。
  2. Bins(組距):每個特征空間子區段的數目
  3. Range(范圍):需要統計的特征的取值范圍。通常情況下,圖像直方圖的灰度范圍為[0, 255]

下面用一個示例說明直方圖的畫法。假設有一副8*8的圖像,其灰度數據如下,為了簡化起見,將灰度區段數(Bins)設為16,編號為b0~b15,具體如下:

[0, 255] = [0, 15] U [16, 31] U...U [240, 255];
其中b0==[0,15],b1=[16,31],...,b15=[240,255]
//灰度值的取值范圍為[0, 255]

灰度值數據

381301671912151803318
154165391066218524
243252622139454683
1392204111118920483
11918860241154196244169
441001720428185166196
1631001720428185166196
2264220558728166146

第一步,將灰度值轉換為Bin的編號,方法是將灰度值除以16,然后舍棄小數部分,如38除以16等于2,130除以16等于8等,轉換后的數據如下:

281011131121
9102040111
15153135340
80126011125
7113159121510
211462121112
1061121111012
14013351109

第二步,統計16個灰度范圍(Bin的編號)的個數,如下表

Bin0123456789101112131415合計
個數665423312367732464

第三步,根據上表,畫出直方圖如下,x軸代表一個灰度范圍,y軸代表個數:
在這里插入圖片描述

由于直方圖只統計數量而不考慮像素在圖像中的位置,因而具有平移性、旋轉和縮放不變性。也正是因為這個原因,兩幅截然不同不同的圖像的直方圖可能是一樣的。

通過對直方圖的分析,可以發現有關亮度(曝光)和對比度的問題,并可以了解一張圖像是否有效利用了整個強度范圍。直方圖的均值和中值可用來描述圖像的亮度,其中中值比均值更具穩健性:直方圖的標準差(或方差)則可以用來描述圖像的對比度。

由于直方圖中數字越大亮度也越大,因此直方圖中的柱形明顯擊中于中間和右側,左側靠近0(黑色)的位置則非常稀疏,這說明這張圖像整體偏亮。直方圖的峰值都集中在左側的圖像往往曝光不足,而擊中在右側的圖像則往往曝光過度。對比度的高低在直方圖上也是一目了然的。如果圖像的大部分像素集中在直方圖的某個范圍,則說明其對比度較低,如果像素擴展至直方圖整個范圍,則對比度較高。

二、直方圖統計

在OpenCV中繪制直方圖需要先進行直方圖統計,然后用繪圖函數把直方圖繪制出來。

//圖像直方圖的數據統計
void Imgproc.calcHist(List<Mat> images, MatOfint channels, Mat mask, Mat hist, MatOfInt histSize, MatOfFloat ranges)
  • image:輸入圖像
  • channels:需要統計直方圖的第幾通道:如輸入圖像是灰度圖,則它的值是0,如是彩色圖像,則用0、1、2代表B、G、R三個通道
  • mask:掩膜,如是整幅圖像的直方圖,則無須定義
  • hist:直方圖計算結束
  • histSize:直方圖被分成多少個取件,即bin的個數
  • ranges:像素取值范圍,通常為0-255

上述函數只負責統計數據,如果想要看到直方圖,則還需要用繪圖函數把直方圖畫出來,但是這里有一個小問題。直方圖統計出來的是灰度值范圍的個數,有的值可能很大,有的則可能很小,要在一張圖像中把它們畫出來需要先統計出這些值的最大值,然后根據比例畫出來。這樣相當繁瑣,而用OpenCV中的normalize()函數進行歸一化就可以解決這個問題。

//對矩陣進行歸一化
void Core.normalize(Mat src, Mat dst, double alpha, double beta, int norm_type)
  • src:輸入圖像
  • dst:輸出矩陣,與src具有同樣的尺寸
  • alpha:歸一化后的上限值
  • beta:歸一化后的上限值
  • norm_type:歸一化類型,常用參數如下:
    • Core.NORM_INF:無窮范數,向量最大值
    • Core.NORM_L1:L1范數,絕對值之和
    • Core.NORM_L2:L2范數,平方和之平方根
    • Core.NORM_L2SQR:L2范數,平方和
    • Core.NORM_MINMAX:偏移歸一化
public class CalcHist {static {OpenCV.loadLocally(); // 自動下載并加載本地庫}public static void main(String[] args) {//讀取圖像灰度圖并顯示Mat src = Imgcodecs.imread("/Users/acton_zhang/J2EE/MavenWorkSpace/opencv_demo/src/main/java/demo1/key.jpg", Imgcodecs.IMREAD_GRAYSCALE);HighGui.imshow("src", src);HighGui.waitKey(0);//參數準備List<Mat> mat = new ArrayList<>();mat.add(src);float[] range = {0, 256};//直方圖統計值范圍Mat hist = new Mat();MatOfFloat histRange = new MatOfFloat(range);//直方圖數據統計并歸一化Imgproc.calcHist(mat, new MatOfInt(0), new Mat(), hist, new MatOfInt(256), histRange);//直方圖尺寸int width = 512;int height = 400;Core.normalize(hist, hist, 0, height, Core.NORM_MINMAX);//將直方圖數據轉存到數組中以便后續使用float[] histData = new float[(int)(hist.total() * hist.channels())];hist.get(0, 0, histData);//繪制直方圖Scalar black = new Scalar(0, 0, 0);Scalar white = new Scalar(255, 255, 255);Mat histImage = new Mat(height, width, CvType.CV_8UC3, black);int binWid = (int)Math.round((double)width / 256);//bin的寬度for (int i = 0; i < 256; i++) {Imgproc.line(histImage, new Point(i * binWid, height), new Point(i * binWid, height - Math.round(histData[i])), white, binWid);}//在屏幕上顯示繪制的直方圖HighGui.imshow("calcHist", histImage);HighGui.waitKey(0);System.exit(0);}
}

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

直方圖:

在這里插入圖片描述

三、直方圖比較

由于直方圖反映了圖像的灰度值的分布特性,因而通過直方圖的比較可以在一定程度上了解兩幅圖像的相似程度。當然,由于兩幅截然不同的圖像的直方圖可能是完全一樣的,這種比較只能作為參考。

//比較兩幅直方圖。此函數適用于一維、二維、三維密集直方圖,但可能不適用于高維稀疏直方圖
double Imgproc.compareHist(Mat h1, Mat h2, int method)
  • h1:第一個直方圖
  • h2:第二個直方圖
  • method:比較方法,如下:

在這里插入圖片描述

public class CompareHist {static {OpenCV.loadLocally(); // 自動下載并加載本地庫}public static void main(String[] args) {//讀取圖像灰度圖并顯示Mat src = Imgcodecs.imread("/Users/acton_zhang/J2EE/MavenWorkSpace/opencv_demo/src/main/java/demo1/pond.png", Imgcodecs.IMREAD_GRAYSCALE);HighGui.imshow("src", src);HighGui.waitKey(0);//對圖像進行中值濾波并顯示Mat src2 = new Mat();Imgproc.medianBlur(src, src2, 5);HighGui.imshow("Median Blur", src2);HighGui.waitKey(0);//直方圖參數設置float[] range = {0, 256};MatOfFloat histRange = new MatOfFloat(range);//圖像1的直方圖數據統計并歸一化Mat hist = new Mat();List<Mat> matList = new LinkedList<>();matList.add(src);Imgproc.calcHist(matList, new MatOfInt(0), new Mat(), hist, new MatOfInt(256), histRange);Core.normalize(hist, hist, 0, 400, Core.NORM_MINMAX);//圖像2的直方圖數據統計并歸一化Mat hist2 = new Mat();List<Mat> matList2 = new LinkedList<>();matList2.add(src2);Imgproc.calcHist(matList2, new MatOfInt(0), new Mat(), hist2, new MatOfInt(256), histRange);Core.normalize(hist2, hist2, 0, 400, Core.NORM_MINMAX);double s = Imgproc.compareHist(hist, hist2, Imgproc.HISTCMP_CORREL);System.out.println("相似度:" + s);System.exit(0);}
}
相似度:0.9987133134938458

程序中用于比較兩幅圖像中一幅是未處理的原圖像。另一幅是經過中值濾波后的圖像。經過比較兩者相似度約為0.9987。由于比較方法用的是相關性比較,完全一致時相似度為1,此結果顯示兩者相似度非常高。

當然,如前所述,直方圖只統計數量而不考慮像素在圖像中的位置,因而兩幅截然不同的圖像的直方圖可能是一樣的。直方圖的比較結果完全匹配也并不能說明兩幅圖像是一樣的,但如果兩幅圖像完全一樣,則它們的直方圖必然是完全匹配的。

四、直方圖均衡化

在曝光不足或曝光過度時,直方圖往往集中在一個區域,而解決問題的方法就是直方圖均衡化。所謂直方圖均衡化,就是盡可能地讓一張圖像的像素占據全部可能的灰度級并且分布均勻,從而具有較高的對比度。直方圖均衡化的原理圖如下:

在這里插入圖片描述

//對圖像進行直方圖均衡化
void Imgproc.equalizeHist(Mat src, Mat dst)
  • src:輸入圖像,必須是8位單通道圖像
  • dst:輸出圖像,和src具有相同的尺寸和數據類型
public class EqualizeHist {static {OpenCV.loadLocally(); // 自動下載并加載本地庫}public static void main(String[] args) {//讀取圖像灰度圖并顯示Mat src = Imgcodecs.imread("/Users/acton_zhang/J2EE/MavenWorkSpace/opencv_demo/src/main/java/demo1/grotto.jpg", Imgcodecs.IMREAD_GRAYSCALE);HighGui.imshow("src", src);HighGui.waitKey(0);//直方圖均衡化并在屏幕上顯示結果Mat dst = new Mat();Imgproc.equalizeHist(src, dst);HighGui.imshow("dst", dst);HighGui.waitKey(0);System.exit(0);}
}

原圖:

在這里插入圖片描述

直方圖均衡化:

在這里插入圖片描述

五、自適應的直方圖均衡化

直方圖均衡對于背景和前景都太亮或太暗的圖像很有效,但是在很多情況下其效果并不理想。直方圖均衡化主要存在以下兩個問題:

  1. 某些區域由于對比度增強過大而成為噪點
  2. 某些區域調整后變得更暗或更亮,從而丟失細節

針對上述兩個問題,先后有人提出了對比度限制直方圖均衡算法(CLHE算法)和自適應直方圖均衡算法(AHE算法)。

CLHE算法在HE算法的基礎上加入了對比度限制,算法中設置了一個直方圖分布的閾值,將超過該閾值的部分均勻地分散到其他Bins中,其原理如下:
在這里插入圖片描述
AHE算法則將圖像分成很多小塊,對每個小塊進行直方圖均衡化,然后將這些小塊拼接起來,但是這樣又產生了新的問題,由于對每個小塊進行均衡化時的參數不同,小塊之間會產生一些邊界。

限制對比度自適應直方圖均衡化(CLAHE算法)綜合了這兩個算法的優點,并通過雙線性差值的方法對小塊進行縫合以消除邊界問題。嚴格的說,自適應的直方圖均衡化算法是指AHE算法,而不是CLAHE算法。不過,為了簡化起見,目前在提起 自適應的直方圖均衡化算法 時所指的基本是CLAHE算法。

為了實現這個算法,OpenCV中專門設置了CLAHE類。CLAHE算法的實現一般需要如下兩步:
1. 創建一個CLAHE類:

CLAHE clahe = Imgproc.createCLAHE();

2. 調用CLAHE.apply()函數進行自適應的直方圖均衡化:

clahe.apply(src, dst);
public class Clahe {static {OpenCV.loadLocally(); // 自動下載并加載本地庫}public static void main(String[] args) {//讀取圖像灰度圖并顯示Mat src = Imgcodecs.imread("F:/IDEAworkspace/opencv/src/main/java/demo2/grotto.jpg", Imgcodecs.IMREAD_GRAYSCALE);HighGui.imshow("src", src);HighGui.waitKey(0);//直方圖均衡化并顯示結果Mat dst = new Mat();Imgproc.equalizeHist(src, dst);HighGui.imshow("dst", dst);HighGui.waitKey(0);//自適應直方圖均衡化并顯示CLAHE clahe = Imgproc.createCLAHE();clahe.apply(src, dst);HighGui.imshow("CLAHE", dst);HighGui.waitKey(0);System.exit(0);}
}

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

直方圖均衡化:
在這里插入圖片描述

自適應直方圖均衡化:

在這里插入圖片描述
總體來看,直方圖均衡化后的圖像黑白對比仍然強烈,佛像背后有一塊黑色陰影,細節根本看不到,另外佛像下方底座部分仍然曝光過度。自適應的直方圖均衡化后的圖像總體對比度降低、因而細節展現更多。得益于分塊均衡化的算法,佛像背后的陰影部分沒有那么黑了,因而可以看到一些細節;另外佛像下方曝光過度問題也大有改善,但是左上角出現了明顯的塊狀,這是原圖中沒有的,這就是CLAHE算法在分塊均衡化后縫合效果不理想的表現,也可以說是這個算法的一個副作用。

六、直方圖反向投影

直方圖反向投影是指先計算某一特征的直方圖模型,然后使用該模型去尋找圖像中是否存在該特征。反向投影可用于檢測輸入圖像在給定圖像中最匹配的區域,因而常用于目標追蹤的MeanShift算法配合使用。

//對圖像直方圖進行反向投影
void Imgproc.calcBackProject(List<Mat> images, MatOfInt channels, Mat hist, Mat dst, MatOfFloat ranges, double scale)
  • images:輸入的圖像集,所有圖像應具有相同的尺寸和數據類型,但通道數可以不同,圖像深度應為CV_8U、CV_16U或CV_32F
  • channels:需要統計的通道索引
  • hist:輸入的直方圖
  • dst:輸出的反向投影圖像
  • ranges:直方圖中bin的取值范圍
  • scale:輸出的反向投影的縮放因子
public class BackProject {static {OpenCV.loadLocally(); // 自動下載并加載本地庫}public static void main(String[] args) {//讀取圖像轉換為HSV色彩空間并顯示Mat src = Imgcodecs.imread("F:/IDEAworkspace/opencv/src/main/java/demo/leaf.png");Mat hsv = new Mat();Imgproc.cvtColor(src, hsv, Imgproc.COLOR_BGR2HSV);HighGui.imshow("leaf", hsv);HighGui.waitKey(0);//將圖像的hue(色調)通道提取至hueList中Mat hue = new Mat(hsv.size(), hsv.depth());List<Mat> hsvList = new LinkedList<>();List<Mat> hueList = new LinkedList<>();hsvList.add(hsv);hueList.add(hue);Core.mixChannels(hsvList, hueList, new MatOfInt(0, 0));//直方圖參數設置int bins = 25;int histSize = Math.max(bins, 2);float[] hueRange = {0, 180};//直方圖數據統計并歸一化Mat hist = new Mat();Imgproc.calcHist(hueList, new MatOfInt(0), new Mat(), hist, new MatOfInt(histSize), new MatOfFloat(hueRange));Core.normalize(hist, hist, 0, 255, Core.NORM_MINMAX);//計算反向投影并顯示Mat backproj = new Mat();Imgproc.calcBackProject(hueList, new MatOfInt(0), hist, backproj, new MatOfFloat(hueRange), 1);HighGui.imshow("calcHist", backproj);HighGui.waitKey(0);System.exit(0);}
}

原圖HSV:
在這里插入圖片描述

反向投影:
在這里插入圖片描述

七、模板匹配

直方圖反向投影可用于檢測輸入圖像在給定圖像中最匹配的區域,但是由于直方圖的局限性,直方圖反向投影得到的匹配結果只能作為參考,如果需要精確匹配,則還需要用到模板匹配。

模板匹配是指在一張圖像中尋找與另一幅模板圖像最佳匹配(相似)區域。所謂模板,就是用來對比的圖像。模板匹配的具體方法是:在待匹配圖像中選擇與模板相同尺寸的滑動窗口,然后不斷地移動滑動窗口,計算其與圖像中相應區域的匹配度,最終匹配度最高的區域即為匹配結果。

//在圖像中尋找與模板匹配的區域
void Imgproc.matchTemplate(Mat image, Mat temp1, Mat result, int method)
  • image:待匹配圖像,要求是8位或32位浮點圖像
  • temp1:模板圖像,其數據類型與待匹配圖像相同,并且尺寸不能大于待匹配圖像
  • result:輸出的匹配圖,必須是32位浮點圖像。如果待匹配圖像的尺寸為WH,模板圖像尺寸為wh,則輸出圖像尺寸為(W-w+1)*(H-h+1)
  • method:匹配方法,可選參數如下,相應計算公式如下表
    • Imgproc.TM_SQDIFF:平方差匹配法。完全匹配時計算值為0,匹配度越低數值越大
    • Imgproc.TM_SQDIFF_NORMED:歸一化平方差匹配法。將平方差匹配法歸一化到0~1
    • Imgproc.TM_CCORR:相關匹配法。0為最差匹配,數值越大匹配效果越好
    • Imgproc.TM_CCORR_NORMED:歸一化相關匹配法。將相關匹配法歸一化到0~1
    • Imgproc.TM_CCOEFF:系數匹配法。數值越大匹配度越高,數值越小匹配度越低
    • Imgproc.TM_CCOEFF_NORMED:歸一化系數匹配法。將系數匹配法歸一化到-1~1,1表示完全匹配,-1表示完全不匹配

由于matchTemplate()函數只是計算各個區域的匹配度,要得到最佳匹配還需要用minMaxLoc()函數來定位:

//尋找矩陣中的最大值和最小值及在矩陣中的位置
MinMaxLocResult Core.minMaxLoc(Mat src)
  • src:輸入矩陣,必須是單通道

在這里插入圖片描述

public class MatchTemplate {static {OpenCV.loadLocally(); // 自動下載并加載本地庫}public static void main(String[] args) {//讀取圖像并顯示Mat src = Imgcodecs.imread("/Users/acton_zhang/J2EE/MavenWorkSpace/opencv_demo/src/main/java/demo1/fish.png");HighGui.imshow("src", src);HighGui.waitKey(0);//讀取模板圖像并顯示Mat template = Imgcodecs.imread("/Users/acton_zhang/J2EE/MavenWorkSpace/opencv_demo/src/main/java/demo1/leaf.png");HighGui.imshow("template", template);HighGui.waitKey(0);//進行模板匹配:結果在result中Mat result = new Mat();Imgproc.matchTemplate(src, template, result, Imgproc.TM_CCOEFF);//取出最大值的位置(TM_CCOEFF模式用最大值)Core.MinMaxLocResult mmr = Core.minMaxLoc(result);Point pt = mmr.maxLoc;//用矩形畫出匹配位置并在屏幕上顯示Scalar red = new Scalar(0, 0, 255);Imgproc.rectangle(src, pt, new Point(pt.x + template.cols(), pt.y + template.rows()), red, 3);HighGui.imshow("match", src);HighGui.waitKey(0);System.exit(0);}
}

原圖:

在這里插入圖片描述

模板:
在這里插入圖片描述

匹配結構:

在這里插入圖片描述

上述程序只能找到最佳匹配,而有時匹配的圖像不止一個,此時就要從matchTemplate()函數的結構中找出所有符合條件的圖像。下面用一個完整的程序說明如何將模板匹配運用于多目標匹配:

public class MatchTemplate2 {static {OpenCV.loadLocally(); // 自動下載并加載本地庫}public static void main(String[] args) {//讀取圖像并顯示Mat src = Imgcodecs.imread("/Users/acton_zhang/J2EE/MavenWorkSpace/opencv_demo/src/main/java/demo2/rose.png");HighGui.imshow("src", src);HighGui.waitKey(0);//讀取模板圖像并顯示Mat template = Imgcodecs.imread("/Users/acton_zhang/J2EE/MavenWorkSpace/opencv_demo/src/main/java/demo2/my.png");HighGui.imshow("template", template);HighGui.waitKey(0);//進行模板匹配,匹配值范圍為-1~1Mat result = new Mat();Imgproc.matchTemplate(src, template, result, Imgproc.TM_CCOEFF_NORMED);System.out.println(result);//參數準備float[] p = new float[3];Scalar red = new Scalar(0, 0, 255);int temprow = template.rows();int tempcol = template.cols();//搜索匹配值>0.8的像素for (int i = 0; i < result.rows(); i++) {for (int j = 0; j < result.cols(); j++) {//獲取像素的匹配值result.get(i, j, p);//匹配值>0.8的像素用矩形畫出if (p[0] > 0.8) {Imgproc.rectangle(src, new Point(j, i), new Point(j + tempcol, i + temprow), red, 3);}}}//顯示匹配結果HighGui.imshow("match", src);HighGui.waitKey(0);System.exit(0);}
}

原圖:

在這里插入圖片描述

模板:

在這里插入圖片描述

匹配結果:

在這里插入圖片描述

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

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

相關文章

通義大模型在文檔自動化處理中的高效部署指南(OCR集成與批量處理優化)

1. 傳統OCR解決方案常面臨識別精度低、版面分析能力弱、處理效率瓶頸等問題。通義大模型憑借其多模態理解和生成能力&#xff0c;為文檔處理領域帶來革命性突破。本文將深入探討如何高效部署通義大模型實現端到端的文檔自動化處理&#xff0c;特別聚焦OCR集成與批量處理優化兩…

Ubuntu20.04通過ssh協議配置遠程終端

一、在目標計算機&#xff08;即被連接的計算機&#xff09;上操作&#xff1a; 1、安裝 OpenSSH 服務器&#xff1a; sudo apt update sudo apt install openssh-server3、啟動并設置 SSH 服務開機自啟&#xff1a; sudo systemctl enable --now ssh二、在源計算機&#xf…

《HTTP權威指南》 第7章 緩存

帶著問題學習&#xff1a; 緩存如何提高性能如何衡量緩存的有效性緩存置于何處作用最大HTTP如何保持緩存副本的新鮮度緩存如何與其他緩存及服務器通信 web緩存是可以自動保存常見文檔副本的HTTP設備。 緩存優點 減少冗余的數據傳輸&#xff0c;節省網絡費用緩解網絡瓶頸問題&…

第十三章 模板

函數模板 函數模板使用 函數模板注意事項 自動類型推導&#xff0c;必須推導出一致的數據類型T,才可以使用 模板必須要確定出T的數據類型&#xff0c;才可以使用 普通函數和函數模板的類型轉化 普通函數隱式類型轉化&#xff08;char轉int&#xff09; 函數模板正常使用不會發生…

云計算-專有網絡VPC

&#x1f310; 什么是 VPC&#xff1f;&#xff08;Virtual Private Cloud&#xff09; VPC&#xff08;Virtual Private Cloud&#xff0c;虛擬私有云&#xff09; 是公有云服務商提供的一種網絡隔離服務&#xff0c;允許用戶在云中創建一個邏輯隔離的私有網絡環境。你可以在這…

關于*gin.Context的理解

關于*gin.Context的理解 作為初學者&#xff0c;在學習go語言用gin開發web時&#xff0c;我對*gin.Context感到困惑。本文章以自我總結為主&#xff0c;大部分為來自詢問ai后的總結&#xff0c;如有問題歡迎指出。 *gin.Context可以理解為一個gin框架的上下文對象指針&#x…

Qt中的OpenGL (6)[坐標系統]

文章目錄 文章說明學習目標目錄結構坐標系統局部空間世界空間觀察空間裁剪空間正射投影矩陣透視投影矩陣組合進入3D世界頂點數據著色器設置數據矩陣設置文章說明 本文是學習OpenGL的筆記,主要參考大神JoeyDeVries的LearnOpenGL第八課《坐標系統》,并將教程中的代碼基于Qt進行…

Spring Aop @After (后置通知)的使用場景?

核心定義 After 是 Spring AOP 中的另一種通知&#xff08;Advice&#xff09;類型&#xff0c;通常被稱為“后置通知”或“最終通知”。 它的核心作用是&#xff1a; 無論目標方法是正常執行完成&#xff0c;還是在執行過程中拋出了異常&#xff0c;After 通知中的代碼 總是…

UNet改進(4):交叉注意力(Cross Attention)-多模態/多特征交互

在計算機視覺領域&#xff0c;UNet因其優異的性能在圖像分割任務中廣受歡迎。本文將介紹一種改進的UNet架構——UNetWithCrossAttention&#xff0c;它通過引入交叉注意力機制來增強模型的特征融合能力。 1. 交叉注意力機制 交叉注意力(Cross Attention)是一種讓模型能夠動態地…

C#里從CSV文件加載BLOB數據字段到數據庫的處理

大量的數據保存在CSV文件, 當需要把這些數據加載到數據庫,然后使用數據庫來共享出去。 就需要把CSV文件導入數據庫, 怎么樣快速地把CSV文件導入數據庫呢? 這個就需要使用類MySqlBulkLoader,它是mariadb數據庫快速導入的方式。 一般使用SQL語句導入是10秒,那么使用這種方…

【后端】負載均衡

長期不定期更新補充。 定義 負載均衡&#xff08;Load Balancing&#xff09;是指將來自客戶端的請求合理分發到多個服務器或服務節點&#xff0c;以提高系統性能、可用性與可靠性。 分工 前端不做負載均衡&#xff0c;前端只發請求&#xff0c;不知道請求去哪臺服務器。 負…

記錄一次:Java Web 項目 CSS 樣式/圖片丟失問題:一次深度排查與根源分析

記錄一次&#xff1a;Java Web 項目 CSS 樣式/圖片丟失問題&#xff1a;一次深度排查與根源分析 **記錄一次&#xff1a;Java Web 項目 CSS 樣式丟失問題&#xff1a;一次深度排查與根源分析****第一層分析&#xff1a;資源路徑問題****第二層分析&#xff1a;服務端跳轉邏輯**…

torchmd-net開源程序是訓練神經網絡潛力

?一、軟件介紹 文末提供程序和源碼下載 TorchMD-NET 提供最先進的神經網絡電位 &#xff08;NNP&#xff09; 和訓練它們的機制。如果有多個 NNP&#xff0c;它可提供高效、快速的實現&#xff0c;并且它集成在 GPU 加速的分子動力學代碼中&#xff0c;如 ACEMD、OpenMM 和 …

在Docker上安裝Mongo及Redis-NOSQL數據庫

應用環境 Ubuntu 20.04.6 LTS (GNU/Linux 5.15.0-139-generic x86_64) Docker version 28.1.1, build 4eba377 文章目錄 一、部署Mongo1. 拉取容器鏡像2. 生成Run腳本2.1 準備條件2.2 參數解讀2.3 實例腳本 3. 實例操作3.1 Mongo bash控制臺3.2 庫表操作 4. MongoDB Compass (G…

Java 編程之責任鏈模式

一、什么是責任鏈模式&#xff1f; 責任鏈模式&#xff08;Chain of Responsibility Pattern&#xff09; 是一種行為型設計模式&#xff0c;它讓多個對象都有機會處理請求&#xff0c;從而避免請求的發送者和接收者之間的耦合關系。將這些對象連成一條鏈&#xff0c;沿著這條…

1、做中學 | 一年級上期 Golang簡介和安裝環境

一、什么是golang Golang&#xff0c;通常簡稱 Go&#xff0c;是由 Google 公司的 Robert Griesemer、Rob Pike 和 Ken Thompson 于 2007 年創建的一種開源編程語言&#xff0c;并在 2009 年正式對外公布。 已經有了很多編程語言&#xff0c;為什么還要創建一種新的編程語言&…

Linux--迷宮探秘:從路徑解析到存儲哲學

上一篇博客我們說完了文件系統在硬件層面的意義&#xff0c;今天我們來說說文件系統在軟件層是怎么管理的。 Linux--深入EXT2文件系統&#xff1a;數據是如何被組織、存儲與訪問的&#xff1f;-CSDN博客 &#x1f30c; 引言&#xff1a;文件系統的宇宙觀 "在Linux的宇宙中…

淘寶商品數據實時獲取方案|API 接口開發與安全接入

在電商數據獲取領域&#xff0c;除了官方 API&#xff0c;第三方數據 API 接入也是高效獲取淘寶商品數據的重要途徑。第三方數據 API 憑借豐富的功能、靈活的服務&#xff0c;為企業和開發者提供了多樣化的數據解決方案。本文將聚焦第三方數據 API 接入&#xff0c;詳細介紹其優…

什么是防抖和節流?它們有什么區別?

文章目錄 一、防抖&#xff08;Debounce&#xff09;1.1 什么是防抖&#xff1f;1.2 防抖的實現 二、節流&#xff08;Throttle&#xff09;2.1 什么是節流&#xff1f;2.2 節流的實現方式 三、防抖與節流的對比四、總結 在前端開發中&#xff0c;我們經常會遇到一些高頻觸發的…

Springboot集成阿里云OSS上傳

Springboot集成阿里云OSS上傳 API 接口描述 DEMO提供的四個API接口&#xff0c;支持不同方式的文件和 JSON 數據上傳&#xff1a; 1. 普通文件上傳接口 上傳任意類型的文件 2. JSON 字符串上傳接口 上傳 JSON 字符串 3. 單個 JSON 壓縮上傳接口 上傳并壓縮 JSON 字符串…