圖像處理之邊緣檢測(C++)

圖像處理之邊緣檢測(C++)


文章目錄

  • 圖像處理之邊緣檢測(C++)
  • 前言
  • 一、Roberts算子
    • 1.原理
    • 2.代碼實現
  • 二、Sobel算子
    • 1.原理
    • 2.代碼實現
  • 三、Prewitt算子
    • 1.原理
    • 2.代碼實現
  • 四、Laplacian算子
    • 1.原理
    • 2.代碼實現
  • 五、LOG算子
    • 1.原理
    • 2.代碼實現
  • 六、DOG算子
    • 1.原理
    • 2.代碼實現
  • 總結


前言

邊緣檢測是圖像處理的基礎,邊緣檢測主要是為了找到圖像中亮度變化劇烈的像素點構成的集合,即圖像的輪廓(邊緣)。
傳統邊緣檢測的主要有Roberts、Sobel、Prewitt、Laplacian、LOG、DOG等方法,本文介紹上述的邊緣檢測算子的實現。
原圖:
原圖


一、Roberts算子

1.原理

Roberts算子是一種斜向偏差分的梯度計算方法,采用對角方向相鄰的兩像素值之差,梯度的大小代表邊緣的強度,梯度的方向與邊緣的走向垂直。它是2X2算子模板。2個卷積核形成了Roberts算子。圖像中的每一個點都用這2個核做卷積。
卷積核形式如下:
卷積核形式
計算公式如下
計算梯度
計算梯度值
備注:采用絕對值相加減少計算量。

2.代碼實現

#include <opencv.hpp>
#include <iostream>/*
* @param const cv::Mat& src		輸入圖像
* @param cv::Mat& dst			輸出圖像
*/
void roberts(const cv::Mat& src, cv::Mat& dst)
{// 創建卷積核cv::Mat kernel_x = (cv::Mat_<float>(2, 2) << 1, 0, 0, -1);cv::Mat kernel_y = (cv::Mat_<float>(2, 2) << 0, 1, -1, 0);// 卷積計算// 卷積核翻轉cv::flip(kernel_x, kernel_x, -1);cv::flip(kernel_y, kernel_y, -1);// 相關性計算cv::Mat dst_x, dst_y;cv::filter2D(src, dst_x, kernel_x.depth(), kernel_x);cv::filter2D(src, dst_y, kernel_y.depth(), kernel_y);// 絕對值轉換cv::convertScaleAbs(dst_x, dst_x);cv::convertScaleAbs(dst_y, dst_y);// 計算梯度dst = dst_x + dst_y;cv::normalize(dst, dst, 0, 255, cv::NORM_MINMAX,CV_8UC1);
}int main()
{// 讀取圖片std::string filepath = "F://work_study//algorithm_demo//regionGrow_test.jpg";cv::Mat src = cv::imread(filepath, cv::IMREAD_GRAYSCALE);if (src.empty()){return -1;}cv::Mat dst;roberts(src, dst);// 保存圖片cv::imwrite("dst.jpg", dst);system("pause");return 0;
}

在這里插入圖片描述

二、Sobel算子

1.原理

Sobel算子根據像素點上下、左右鄰點灰度加權差,在邊緣處達到極值這一現象檢測邊緣。它結合高斯平滑和微分求導,用來計算圖像灰度函數的近似梯度(讀者可以嘗試分離卷積核,即可看出卷積核是由一個求解水平梯度或者垂直梯度的卷積核和非歸一化的高斯平滑相乘得到)。在圖像的任何一點使用此算子,將會產生對應的梯度矢量或是其法矢量。它對噪聲具有平滑作用,提供較為精確的邊緣方向信息,邊緣定位精度不夠高。

卷積核形式:
卷積核
計算公式如下:
卷積
幅值
在這里插入圖片描述

2.代碼實現

/*
* @param const cv::Mat& src		輸入圖像
* @param cv::Mat& dst			輸出圖像
* @brief sobel算子實現
*/
void sobel(const cv::Mat& src, cv::Mat& dst) {// 創建卷積核cv::Mat kernel_x = (cv::Mat_<float>(3,3) << -1, 0, 1, -2, 0, 2, -1, 0, 1);cv::Mat kernel_y = (cv::Mat_<float>(3, 3) << 1, 2, 1, 0, 0, 0, -1, -2, -1);// 卷積運算// 翻轉卷積核cv::flip(kernel_x, kernel_x, -1);cv::flip(kernel_y, kernel_y, -1);// 相關性計算cv::Mat dst_x, dst_y;cv::filter2D(src, dst_x, kernel_x.depth(), kernel_x);cv::filter2D(src, dst_y, kernel_y.depth(), kernel_y);cv::convertScaleAbs(dst_x, dst_x);cv::convertScaleAbs(dst_y, dst_y);cv::normalize(dst_x + dst_y, dst, 0, 255, cv::NORM_MINMAX, CV_8U);
}int main()
{// 讀取圖片std::string filepath = "F://work_study//algorithm_demo//regionGrow_test.jpg";cv::Mat src = cv::imread(filepath, cv::IMREAD_GRAYSCALE);if (src.empty()){return -1;}cv::Mat dst;sobel(src, dst);// 保存圖片cv::imwrite("dst.jpg", dst);system("pause");return 0;
}

結果

三、Prewitt算子

1.原理

Prewitt算子的計算步驟如sobel算子,將方向的差分運算和局部平均相結合的方法(通過分離卷積核即可得出結論,不多贅述),也是取水平和垂直兩個卷積核來分別對圖像中各個像素點做卷積運算,所不同的是,Sobel 算子是先做加權平均然后再微分,Prewitt 算子是先平均后求微分。由于采用了局部灰度平均,容易檢測出偽邊緣,且邊緣定位精度較低。
卷積核形式:
在這里插入圖片描述
計算公式:
幅值

2.代碼實現

/*
* @param const cv::Mat& src		輸入圖像
* @param cv::Mat& dst			輸出圖像
* @brief prewitt算子實現
*/
void prewitt(const cv::Mat& src, cv::Mat& dst) {// 創建卷積核cv::Mat kernel_x = (cv::Mat_<float>(3, 3) << -1, 0, 1, -1, 0, 1, -1, 0, 1);cv::Mat kernel_y = (cv::Mat_<float>(3, 3) << 1, 1, 1, 0, 0, 0, -1, -1, -1);// 卷積運算// 翻轉卷積核cv::flip(kernel_x, kernel_x, -1);cv::flip(kernel_y, kernel_y, -1);// 相關性計算cv::Mat dst_x, dst_y;cv::filter2D(src, dst_x, kernel_x.depth(), kernel_x);cv::filter2D(src, dst_y, kernel_y.depth(), kernel_y);cv::convertScaleAbs(dst_x, dst_x);cv::convertScaleAbs(dst_y, dst_y);cv::normalize(dst_x + dst_y, dst, 0, 255, cv::NORM_MINMAX, CV_8U);
}int main()
{// 讀取圖片std::string filepath = "F://work_study//algorithm_demo//regionGrow_test.jpg";cv::Mat src = cv::imread(filepath, cv::IMREAD_GRAYSCALE);if (src.empty()){return -1;}cv::Mat dst;prewitt(src, dst);// 保存圖片cv::imwrite("prewitt_dst.jpg", dst);system("pause");return 0;
}

prewitt

四、Laplacian算子

1.原理

它不依賴于邊緣方向的二階微分算子,對圖像中的階躍型邊緣點定位準確,該算子對噪聲非常敏感,它使噪聲成分得到加強,這兩個特性使得該算子容易丟失一部分邊緣的方向信息,造成一些不連續的檢測邊緣,同時抗噪聲能力比較差,由于其算法可能會出現雙像素邊界,常用來判斷邊緣像素位于圖像的明區或暗區。

卷積核

2.代碼實現

/*
* @param const cv::Mat& src		輸入圖像
* @param cv::Mat& dst			輸出圖像
* @brief prewitt算子實現
*/
void laplacian(const cv::Mat& src, cv::Mat& dst) {// 創建卷積核//cv::Mat kernel = (cv::Mat_<float>(3, 3) << 0, 1, 0, 1, -4, 1, 0, 1, 0);cv::Mat kernel = (cv::Mat_<float>(3, 3) << 1, 1, 1, 1, -8, 1, 1, 1, 1);// 卷積運算// 翻轉卷積核cv::flip(kernel, kernel, -1);// 相關性計算cv::filter2D(src, dst, kernel.depth(), kernel);cv::convertScaleAbs(dst, dst);cv::normalize(dst, dst, 0, 255, cv::NORM_MINMAX, CV_8U);
}int main()
{// 讀取圖片std::string filepath = "F://work_study//algorithm_demo//regionGrow_test.jpg";cv::Mat src = cv::imread(filepath, cv::IMREAD_GRAYSCALE);if (src.empty()){return -1;}cv::Mat dst;laplacian(src, dst);// 保存圖片cv::imwrite("laplacian.jpg", dst);system("pause");return 0;
}

result

五、LOG算子

1.原理

高斯拉普拉斯算子Lapacian of gaussian先對圖像進行高斯平滑濾波處理,然后再與Laplacian算子進行卷積。其處理過程:灰度-高斯-拉普拉斯-負值為0。
LOG

2.代碼實現

/*
* @param const cv::Mat& src		輸入圖像
* @param cv::Mat& dst			輸出圖像
* @brief LOG算子實現
*/
void LOG(const cv::Mat& src, cv::Mat& dst) {// 創建卷積核cv::Mat kernel = (cv::Mat_<float>(5, 5) << 0, 0, -1, 0, 0,0, -1, -2, -1, 0,-1, -2, 16, -2, -1,0, -1, -2, -1, 0,0, 0, -1, 0, 0);// 卷積運算(卷積核對稱無需翻轉)cv::filter2D(src, dst, kernel.depth(), kernel);cv::threshold(dst, dst, 0, 255, cv::THRESH_BINARY);dst.convertTo(dst, CV_8U);
}/*
* @param const cv::Mat& src		輸入圖像
* @param cv::Mat& dst			輸出圖像
* @brief LOG算子實現
*/
void LOG1(const cv::Mat& src, cv::Mat& dst) {// 高斯濾波cv::GaussianBlur(src, dst, cv::Size(5, 5),0.5);// laplacianlaplacian(dst, dst);cv::threshold(dst, dst, 0, 255, cv::THRESH_BINARY);dst.convertTo(dst, CV_8U);
}int main()
{// 讀取圖片std::string filepath = "F://work_study//algorithm_demo//regionGrow_test.jpg";cv::Mat src = cv::imread(filepath, cv::IMREAD_GRAYSCALE);if (src.empty()){return -1;}cv::Mat dst;LOG(src, dst);// 保存圖片cv::imwrite("LOG.jpg", dst);system("pause");return 0;
}

LOG

六、DOG算子

1.原理

Difference of Gaussian(DOG)是高斯函數的差分。它是可以通過將圖像與高斯函數進行卷積得到一幅圖像的低通濾波結果,它對高斯拉普拉斯LoG的近似,在某一尺度上的特征檢測可以通過對兩個相鄰高斯尺度空間的圖像相減,得到DoG的響應值圖像。
公式證明:
證明
計算步驟:
使用兩個不同標準差的高斯核平滑圖像,然后結果相減,負值為0,獲得邊緣檢測結果。

2.代碼實現

*
* @param const cv::Mat& src		輸入圖像
* @param cv::Mat& dst			輸出圖像
* @brief DOG算子實現
*/
void DOG(const cv::Mat& src, cv::Mat& dst,double sigma,int k) {cv::Mat dst_x, dst_y;cv::GaussianBlur(src, dst_x, cv::Size(3, 3), sigma);cv::GaussianBlur(src, dst_y, cv::Size(3, 3), k*sigma);dst = dst_x - dst_y;cv::threshold(dst, dst, 0, 255, cv::THRESH_BINARY);dst.convertTo(dst, CV_8U);
}int main()
{// 讀取圖片std::string filepath = "F://work_study//algorithm_demo//regionGrow_test.jpg";cv::Mat src = cv::imread(filepath, cv::IMREAD_GRAYSCALE);if (src.empty()){return -1;}cv::Mat dst;DOG(src, dst,1,2);// 保存圖片cv::imwrite("DOG.jpg", dst);system("pause");return 0;
}

DOG


總結

本文介紹了圖像處理中的邊緣檢測算法,包括了Roberts、Sobel、Prewitt、laplacian、DOG、LOG等算子的C++實現和原理介紹,歡迎大家指出問題和交流討論。

參考資料:
高斯濾波(Gauss filtering)
圖像處理 | 最常用的邊緣檢測詳解與代碼(Robert, Sober, Prewitt, Canny, Kirsch, Laplacian, LOG, DOG算子)
LOG算子實現

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

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

相關文章

完全匹配企業需求的替代FTP升級軟件怎么找

企業在處理數據傳輸時&#xff0c;效率和安全性是關鍵。盡管傳統的FTP曾被廣泛采用&#xff0c;但因其傳輸慢、安全性不足和難以管理等問題&#xff0c;已不再滿足現代企業的需求。許多企業正在尋找能夠滿足其需求的FTP替代方案&#xff0c;但市場上選擇眾多&#xff0c;找到合…

Python01:初入Python(Mac)

Python環境準備 下載Python&#xff1a;官網https://www.python.org/ 下載PyCharm&#xff1a;官網https://www.jetbrains.com/pycharm/download Python與PyCharm的關系 Python&#xff08;解釋器&#xff09;&#xff1a;機器語言—>翻譯人員–>翻譯成電腦能讀懂的 PyC…

STM32應用開發進階--SPI總線(7腳OLED中景園ss1306+HAL庫_硬件SPI/軟件模擬SPI)

實現目標 1、掌握SPI總線基礎知識&#xff1b; 2、會使用軟件模擬SPI總線和STM32硬件SPI總線&#xff1b; 3、 學會STM32CubeMX軟件關于SPI的配置; 4、掌握OLED顯示屏驅動&#xff1b; 5、具體目標&#xff1a;&#xff08;1&#xff09;用STM32硬件SPI驅動OLED顯示“你好…

JAVA實現定時任務 從指定時間開始每隔 n 天執行一次, 可刪除重設

本文描述的使用 Java 自帶的 ScheduledExecutorService 來實現這個業務,直接看代碼 涉及到的參數說明: ScheduledTaskManager 類負責管理定時任務的創建、取消和重設。scheduleTask 方法用于創建定時任務。它接受任務名稱、開始時間、執行間隔和任務本身作為參數。cancelTask 方…

抽煙行為檢測:從傳統巡查到智能算法

在當前人工智能和計算機視覺技術的迅猛發展下&#xff0c;基于視覺分析的抽煙行為檢測算法成為一種高效的技術手段。此類算法通常依賴于深度學習模型&#xff0c;特別是卷積神經網絡&#xff08;CNN&#xff09;&#xff0c;通過對攝像頭捕捉的視頻流進行實時分析&#xff0c;能…

在舊版 Nginx 官方 Dockerfile 上集成第三方模塊的探索

問題背景 線上生產環境用的 nginx 1.21, 然后由于新功能引入的一個問題&#xff0c;需要使用第三方模塊 ngx_http_subs_filter_module&#xff0c;目的是使用正則表達式來移除響應結果中的某些數據。 由于這個客戶的環境非常重要&#xff0c;組內的大哥們也不敢隨便升級 ngin…

網絡安全、信息安全、數據安全的定義與區別

信息安全 信息安全是指信息的保密性、完整性、可用性和真實性的保持。從定義角度來說&#xff0c;信息安全沒有嚴格標準定義&#xff0c;但從信息安全涉及的內容出發&#xff0c;信息安全確保信息存儲或傳輸中的信息&#xff0c;不被他人有意或無意的竊取與破壞。這里的“信息”…

Vue3+ts(day07:pinia)

學習源碼可以看我的個人前端學習筆記 (github.com):qdxzw/frontlearningNotes 覺得有幫助的同學&#xff0c;可以點心心支持一下哈&#xff08;筆記是根據b站上學習的尚硅谷的前端視頻【張天禹老師】&#xff0c;記錄一下學習筆記&#xff0c;用于自己復盤&#xff0c;有需要學…

ENVI光譜識別指導采礦管理者監測銅礦分布

圣地亞哥SRGIS的GIS專家Chile需要利用影像光譜信號勘察Chuquicamata的銅礦分布。 解決方案 Chuquicamata是世界上最大的斑巖銅礦分布區。SRGIS發現西部地區只有有限的礦物和貧瘠的巖石&#xff0c;但東部有銅礦分布。為了進一步測定礦藏的情況&#xff0c;他們開發出一套程序&a…

PyTorch中的形狀變換術:reshape、view與permute的區別與聯系

在PyTorch中&#xff0c;reshape、view 和 permute 都是用于改變張量&#xff08;Tensor&#xff09;形狀&#xff08;shape&#xff09;的方法&#xff0c;但它們各自的功能和用途有所不同。 view: view方法用于將張量重新整形為具有指定形狀的張量。使用view時&#xff0c;必…

NoSQL Redis配置與優化

一、關系數據庫與非關系型數據庫 1. 關系型數據庫&#xff1a; 關系型數據庫是一個結構化的數據庫&#xff0c;創建在關系模型&#xff08;二維表格模型&#xff09;基礎上&#xff0c;一般面向于記錄。 SQL 語句&#xff08;標準數據查詢語言&#xff09;就是一種基于關系型…

【Python】pandas連續變量分箱

路過了學校花店 荒野到海邊 有一種浪漫的愛 是浪費時間 徘徊到繁華世界 才發現你背影 平凡得特別 繞過了城外邊界 還是沒告別 愛錯過了太久 反而錯得完美無缺 幸福兜了一個圈 &#x1f3b5; 林宥嘉《兜圈》 import pandas as pd import numpy as np from sklearn.model_selecti…

redis核心面試題一(架構原理+RDB+AOF)

文章目錄 0. redis與mysql區別1. redis是單線程架構還是多線程架構2. redis單線程為什么這么快3. redis過期key刪除策略4. redis主從復制架構原理5. redis哨兵模式架構原理6. redis高可用集群架構原理7. redis持久化之RDB8. redis持久化之AOF9. redis持久化之混合持久化 0. red…

窮人如何翻身賺錢?不妨試試這5個冷門生意,干好了,收入相當不錯

根據統計數據&#xff0c;我國月收入超過3000元的人口已超過4億&#xff0c;這意味著仍有約10億人的月收入低于3000元。正因為如此&#xff0c;網絡上許多人都自嘲為“窮人”。 然而&#xff0c;窮人真的無法改變自己的命運嗎&#xff1f;并非如此。對于渴望賺錢的窮人來說&am…

gpt2使用ggml推理

gpt2使用ggml推理 ggml/examples/gpt-2/main-backend.cpp : #include "ggml/ggml.h" #include "ggml/ggml-alloc.h" #include "ggml/ggml-backend.h"#ifdef GGML_USE_CUDA #include "ggml-cuda.h" #endif#ifdef GGML_USE_METAL #inc…

傳統藍牙模塊BR/EDR與低功耗藍牙模塊有什么區別?

傳統藍牙模塊BR/EDR與低功耗藍牙模塊有什么區別&#xff1f;下面跟隨美迅物聯網MesoonRF從多個維度來了解。   概述&#xff1a;低功耗藍牙采用了高斯頻移鍵控&#xff08;GFSK&#xff09;。這里我們先拋開藍牙的協議&#xff0c;單純從Radio的角度看收發通信&#xff0c;Ra…

【Crypto】Url編碼

文章目錄 Url編碼解題感悟 Url編碼 Url編碼 搞定 小小flag&#xff0c;拿下&#xff01; 解題感悟 有點餓了…

day 1: 738. 單調遞增的數字

738. 單調遞增的數字 當且僅當每個相鄰位數上的數字 x 和 y 滿足 x < y 時&#xff0c;我們稱這個整數是單調遞增的。 給定一個整數 n &#xff0c;返回 小于或等于 n 的最大數字&#xff0c;且數字呈 單調遞增 。 示例1&#xff1a; 輸入&#xff1a;n 10 輸出&#xff1a…

圖數據庫助力供應鏈柔性升級

導讀 當今市場環境受短視頻等流媒體影響&#xff0c;任何風險事件在社交網絡中傳播速度極其迅速&#xff0c;留給企業的反應時間按分秒計&#xff0c;傳統供應鏈的年度計劃面對劇烈變化的市場環境已失去意義。此外&#xff0c;受近年局勢動蕩的影響&#xff0c;市場需求和供應…

APISIX-簡單使用

APISIX-簡單使用 這個工具還是很不錯的&#xff0c;可視化的配置很清晰 &#xff0c; 想用NGINX的配置模式也是可以的&#xff0c;就是要去修改配置文件了。 APISIX&#xff0c;一個很不錯的可視化工具&#xff0c;用來代替Nginx相當不錯&#xff0c;可作為Nginx的平替方案&…