OpenCV 筆記(39):頻域中的拉普拉斯算子

1. 拉普拉斯算子

在該系列的第八篇文章中,我們曾經介紹過在二維空間拉普拉斯算子的定義為:

這是對函數? ?的二階偏導數之和。

2. 拉普拉斯算子的傅里葉變換及其推導

在該系列的第三十二篇文章中,我們曾給介紹過下面的公式

二維連續傅里葉變換:

二維連續傅里葉逆變換:

下面,我們嘗試推導一下拉普拉斯算子在頻域中的表示。首先考慮傅里葉變換的性質,特別是微分運算的傅里葉變換性質:

  • 一階微分:在空間域中對 x 方向的微分變換為:

  • 二階微分:在空間域中對 x 方向的二階微分變換:

同理,

現在,可以直接將拉普拉斯算子作用在? ?上的結果進行傅里葉變換:

在頻域中,由之前介紹過的公式可知? ?的傅里葉變換是? ,即?

拉普拉斯算子的作用等價于對? ?乘以一個因子:

π

這個乘積意味著:頻率越高(u 或 v 越大),乘的因子絕對值越大,也就是高頻成分被放大。因此頻域中的拉普拉斯算子常用于邊緣檢測、銳化等圖像處理任務。

3. 使用 OpenCV C++ 實現頻域的拉普拉斯算子

下面的例子,實現頻域拉普拉斯算子,并且對原圖進行銳化。

在頻域中,銳化操作相當于將原圖頻譜與拉普拉斯響應疊加。具體公式為:

其中 k 是一個控制銳化強度的正數。從空間域視角,這等價于:

#include?<opencv2/opencv.hpp>
#include?<iostream>usingnamespace?cv;
usingnamespacestd;// 創建頻域拉普拉斯濾波器
Mat?createLaplacianFilter(Size size)?{Mat laplacianFilter = Mat::zeros(size, CV_32FC2);int?center_row = laplacianFilter.rows /?2;int?center_col = laplacianFilter.cols /?2;float?factor = (2?* CV_PI) * (2?* CV_PI);?// 計算 (2*PI)^2for?(int?i =?0; i < laplacianFilter.rows; i++) {for?(int?j =?0; j < laplacianFilter.cols; j++) {float?u = (float)(i - center_row);float?v = (float)(j - center_col);float?d_squared = u * u + v * v;laplacianFilter.at<Vec2f>(i, j)[0] = -factor * d_squared;?// ?(2π)^2(u^2+v^2)laplacianFilter.at<Vec2f>(i, j)[1] =?0;}}return?laplacianFilter;
}// 對單個通道應用頻域拉普拉斯銳化并返回處理后頻域圖像的幅度譜
Mat?processChannelAndGetProcessedMag(const?Mat& src, Mat& dst,?double?alpha)?{int?m = getOptimalDFTSize(src.rows);int?n = getOptimalDFTSize(src.cols);Mat padded;copyMakeBorder(src, padded,?0, m - src.rows,?0, n - src.cols, BORDER_CONSTANT, Scalar::all(0));// 創建頻域圖像容器 (復數)Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};Mat complexImg;merge(planes,?2, complexImg);// 進行傅里葉變換 (DFT)dft(complexImg, complexImg);// 創建拉普拉斯濾波器Mat laplacianFilter = createLaplacianFilter(complexImg.size());// 應用拉普拉斯濾波器Mat resultFreq;mulSpectrums(complexImg, laplacianFilter, resultFreq,?0);// 計算處理后頻域圖像的幅度譜 (用于可視化)Mat magProcessed;Mat processedPlanes[2];split(resultFreq, processedPlanes);magnitude(processedPlanes[0], processedPlanes[1], magProcessed);magProcessed += Scalar::all(1);?// 避免 log(0)log(magProcessed, magProcessed);normalize(magProcessed, magProcessed,?0,?1, NORM_MINMAX);int?cx_processed = magProcessed.cols /?2;int?cy_processed = magProcessed.rows /?2;Mat?q0_processed(magProcessed, Rect(0,?0, cx_processed, cy_processed));Mat?q1_processed(magProcessed, Rect(cx_processed,?0, cx_processed, cy_processed));Mat?q2_processed(magProcessed, Rect(0, cy_processed, cx_processed, cy_processed));Mat?q3_processed(magProcessed, Rect(cx_processed, cy_processed, cx_processed, cy_processed));Mat tmp_processed;q0_processed.copyTo(tmp_processed);q3_processed.copyTo(q0_processed);tmp_processed.copyTo(q3_processed);q1_processed.copyTo(tmp_processed);q2_processed.copyTo(q1_processed);tmp_processed.copyTo(q2_processed);// 進行傅里葉逆變換Mat resultImg;idft(resultFreq, resultImg, DFT_REAL_OUTPUT);// 裁剪回原始圖像大小resultImg = resultImg(Rect(0,?0, src.cols, src.rows));// 歸一化到 0-255 并轉換為 CV_8UMat resultImg_normalized;normalize(resultImg, resultImg_normalized,?0,?255, NORM_MINMAX, CV_8U);// 銳化addWeighted(src, alpha, resultImg_normalized, (1?- alpha),?0, dst);return?magProcessed;
}int?main()?{Mat src = imread(".../girl.jpg");if?(src.empty()) {cout?<<?"無法加載圖像"?<<?endl;return-1;}// 通道分離vector<Mat> channels;split(src, channels);// 對每個通道應用頻域拉普拉斯銳化并獲取處理后頻域圖像的幅度譜double?alpha =?1.5;?// 銳化強度因子Mat sharpenedB, sharpenedG, sharpenedR;Mat processedMagB = processChannelAndGetProcessedMag(channels[0], sharpenedB, alpha);Mat processedMagG = processChannelAndGetProcessedMag(channels[1], sharpenedG, alpha);Mat processedMagR = processChannelAndGetProcessedMag(channels[2], sharpenedR, alpha);// 合并銳化后的通道vector<Mat> sharpenedChannels = {sharpenedB, sharpenedG, sharpenedR};Mat sharpenedImg;merge(sharpenedChannels, sharpenedImg);imshow("src", src);imshow("Processed Magnitude Spectrum (Blue Channel)", processedMagB);imshow("Processed Magnitude Spectrum (Green Channel)", processedMagG);imshow("Processed Magnitude Spectrum (Red Channel)", processedMagR);imshow("Sharpened Color Image", sharpenedImg);waitKey(0);return0;
}
原圖和銳化后的圖.png
原圖和銳化后的圖.png

頻域拉普拉斯響應(即拉普拉斯濾波器作用后的圖像)

頻域拉普拉斯響應通常不適合直接顯示:

1. 拉普拉斯響應具有正負值對稱性(不是圖像強度)

  • 拉普拉斯是一種二階微分算子,其結果表示圖像的邊緣變化強度和方向(凸或凹)。

  • 拉普拉斯響應值可能是正的或負的,而標準圖像通道(如CV_8U)不能表達負值

  • 直接顯示會丟失符號信息:正負邊緣變得無法分辨。

2. 值域動態范圍極大,不適合線性可視化

頻域中經過拉普拉斯濾波后,結果的值可能在很大的范圍內波動(甚至數萬級別),遠遠超出 [0, 255]。直接轉換為 8 位圖像會導致:

  • 要么強烈壓縮 → 對比度喪失(畫面幾乎全灰或全白)

  • 要么飽和溢出 → 出現大片“過曝”或“過暗”現象

3. 響應是中間量,本身不代表直觀圖像內容。

所以,例子中展示了幅度譜,它是對頻域響應的一種可視化方式。

各個通道處理后的幅度譜.png
各個通道處理后的幅度譜.png

4. 總結

在頻域中,拉普拉斯算子通過傅里葉變換將空間域的微分操作轉換為頻域的乘法操作。主要用于增強圖像高頻成分以突出邊緣和細節,典型應用包括圖像銳化(通過逆變換疊加原圖與拉普拉斯響應)、邊緣檢測(抑制低頻保留高頻突變信號)、頻域濾波器設計(結合高低通濾波實現帶通或帶阻效果)以及圖像恢復中的正則化約束(抑制噪聲)。它是圖像增強與分析的非常有用的工具。

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

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

相關文章

入職軟件開發與實施工程師了后........

時隔幾個月沒有創作的我又回來了&#xff0c;這幾個月很忙&#xff0c;我一直在找工作&#xff0c;在自考&#xff08;順便還處理了一下分手的事&#xff09;&#xff0c;到處奔波&#xff0c;心力交瘁。可能我骨子里比較傲吧。我不愿意著急謀生&#xff0c;做我不愿意做的普通…

多卡跑ollama run deepseek-r1

# 設置環境變量并啟動模型 export CUDA_VISIBLE_DEVICES0,1,2,3 export OLLAMA_SCHED_SPREAD1 # 啟用多卡負載均衡 ollama run deepseek-r1:32b 若 deepseek-r1:32b 的顯存需求未超過單卡容量&#xff08;如單卡 24GB&#xff09;&#xff0c;Ollama 不會自動啟用多卡 在run…

09、底層注解-@Import導入組件

09、底層注解-Import導入組件 Import是Spring框架中的一個注解&#xff0c;用于將組件導入到Spring的應用上下文中。以下是Import注解的詳細介紹&#xff1a; #### 基本用法 - **導入配置類** java Configuration public class MainConfig { // 配置內容 } Configuration Impo…

題解:P12207 [藍橋杯 2023 國 Python B] 劃分

鏈接 題目描述 給定 40 個數&#xff0c;請將其任意劃分成兩組&#xff0c;每組至少一個元素。每組的權值為組內所有元素的和。劃分的權值為兩組權值的乘積。請問對于以下 40 個數&#xff0c;劃分的權值最大為多少。 5160 9191 6410 4657 7492 1531 8854 1253 4520 9231126…

配置ssh服務-ubuntu到Windows拷貝文件方法

背景&#xff1a; 在工作中&#xff0c;需要頻繁從ubuntu到Windows拷貝文件&#xff0c;但有時間總是無法拷出&#xff0c;每次重啟虛擬機又比較麻煩并且效率較低。可以使用scp服務進行拷貝&#xff0c;不僅穩定而且高效&#xff0c;現將配置過程進行梳理&#xff0c;以供大家參…

線程池模式與C#中用法

一、線程池模式解析 1. 核心概念 線程池是一種 管理線程生命周期的技術&#xff0c;主要解決以下問題&#xff1a; 減少線程創建/銷毀開銷&#xff1a;復用已存在的線程 控制并發度&#xff1a;避免無限制創建線程導致資源耗盡 任務隊列&#xff1a;有序處理異步請求 2. …

設置IDEA打開新項目使用JDK17

由于最近在學習Spring-AI&#xff0c;所以JDK8已經不適用了&#xff0c;但是每次創建新項目都還是JDK8&#xff0c;每次調來調去很麻煩 把Projects和SDKs都調整為JDK17即可 同時&#xff0c;Maven也要做些更改&#xff0c;主要是添加build標簽 <build><plugins>&…

初識MySQL · 索引

目錄 前言&#xff1a; 重溫磁盤 認識索引 為什么這么做&#xff0c;怎么做 重談page 聚簇索引VS非聚簇索引 回表查詢 索引分類 前言&#xff1a; 前文我們主要是介紹了MySQL的一些基本操作&#xff0c;增刪查改一類的操作都介紹了&#xff0c;并且因為大多數情況下&am…

MySQL——7、復合查詢和表的內外連接

復合查詢和表的內外連接 1、基本查詢回顧2、多表查詢3、自連接4、子查詢4.1、單行子查詢4.2、多行子查詢4.3、多列子查詢4.4、在from子句中使用子查詢4.5、合并查詢 5、表的內連和外連5.1、內連接5.2、外連接5.2.1、左外連接5.2.2、右外連接 1、基本查詢回顧 1.1、查詢工資高于…

MYSQL故障排查和環境優化

一、MySQL故障排查 1. 單實例常見故障 &#xff08;1&#xff09;連接失敗類問題 ERROR 2002 (HY000): Cant connect to MySQL server 原因&#xff1a;MySQL未啟動或端口被防火墻攔截。 解決&#xff1a;啟動MySQL服務&#xff08;systemctl start mysqld&#xff09;或開放…

7GB顯存如何部署bf16精度的DeepSeek-R1 70B大模型?

構建RAG混合開發---PythonAIJavaEEVue.js前端的實踐-CSDN博客 服務容錯治理框架resilience4j&sentinel基礎應用---微服務的限流/熔斷/降級解決方案-CSDN博客 conda管理python環境-CSDN博客 快速搭建對象存儲服務 - Minio&#xff0c;并解決臨時地址暴露ip、短鏈接請求改…

數字圖像處理——圖像壓縮

背景 圖像壓縮是一種減少圖像文件大小的技術&#xff0c;旨在在保持視覺質量的同時降低存儲和傳輸成本。隨著數字圖像的廣泛應用&#xff0c;圖像壓縮在多個領域如互聯網、移動通信、醫學影像和衛星圖像處理中變得至關重要。 技術總覽 當下圖像壓縮JPEG幾乎一統天下&#xff…

抖音視頻怎么去掉抖音號水印

你是不是經常遇到這樣的煩惱&#xff1f;看到喜歡的抖音視頻&#xff0c;想保存下來分享給朋友或二次創作&#xff0c;卻被抖音號水印擋住了畫面&#xff1f;別著急&#xff0c;今天教你幾種超簡單的方法&#xff0c;輕松去除水印&#xff0c;高清無水印視頻一鍵保存&#xff0…

RISC-V 開發板 MUSE Pi Pro PCIE 測試以及 fio 崩潰問題解決

視頻講解&#xff1a; RISC-V 開發板 MUSE Pi Pro PCIE 測試以及 fio 崩潰問題解決 板子上有一個m.2的pcie插槽&#xff0c;k1有三個pcie控制器&#xff0c;pcie0和usb3復用一個phy&#xff0c;所以實際開發板就兩個&#xff0c;測試的話&#xff0c;上一個nvme硬盤&#xff0c…

超級管理員租戶資源初始化與授權管理設計方案

背景說明 在多租戶系統中&#xff0c;資源&#xff08;如功能模塊、系統菜單、服務能力等&#xff09;需按租戶維度進行授權管理。超級管理員在創建新租戶時&#xff0c;需要初始化該租戶的資源授權信息。 兩種可選方案 方案描述方案 A&#xff1a;前端傳入選中的資源列表創…

stm32week16

stm32學習 十一.中斷 4.使用中斷 EXTI的配置步驟&#xff1a; 使能GPIO時鐘設置GPIO輸入模式使能AFIO/SYSCFG時鐘設置EXTI和IO對應關系設置EXTI屏蔽&#xff0c;上/下沿設置NVIC設計中斷服務函數 HAL庫的使用&#xff1a; 使能GPIO時鐘&#xff1a;__HAL_RCC_GPIOx_CLK_EN…

什么是RDMA?

什么是RDMA&#xff1f; RDMA(RemoteDirect Memory Access)技術全稱遠程直接內存訪問&#xff0c;就是為了解決網絡傳輸中服務器端數據處理的延遲而產生的。它將數據直接從一臺計算機的內存傳輸到另一臺計算機&#xff0c;無需雙方操作系統的介入。這允許高吞吐、低延遲的網絡…

golang 安裝gin包、創建路由基本總結

文章目錄 一、安裝gin包和熱加載包二、路由簡單場景總結 一、安裝gin包和熱加載包 首先終端新建一個main.go然后go mod init ‘項目名稱’執行以下命令 安裝gin包 go get -u github.com/gin-gonic/gin終端安裝熱加載包 go get github.com/pilu/fresh終端輸入fresh 運行 &…

【數據結構篇】鏈式結構二叉樹

目錄&#xff1a; 一 二叉鏈的概念與結構&#xff1a; 1.1 概念&#xff1a; 1.2 結構&#xff1a; 二 二叉鏈的實現&#xff1a; 2.1 二叉樹的構建&#xff1a; 2.2 二叉樹的遍歷&#xff1a; 2.2.1 前序遍歷&#xff1a; 2.2.2 中序遍歷&#xff1a; 2.2.3 后序遍歷…

【MySQL】02.數據庫基礎

1. 數據庫的引入 之前存儲數據用文件就可以了&#xff0c;為什么還要弄個數據庫? 文件存儲存在安全性問題&#xff0c;文件不利于數據查詢和管理&#xff0c;文件不利于存儲海量數據&#xff0c;文件在程序中控制不方便。而為了解決上述問題&#xff0c;專家們設計出更加利于…