Canny算子

Canny算子_百度百科 (baidu.com)icon-default.png?t=N7T8https://baike.baidu.com/item/Canny%E7%AE%97%E5%AD%90/8821789?fr=ge_ala

圖像處理中最經典的邊沿檢測算法: Canny邊緣檢測_嗶哩嗶哩_bilibiliicon-default.png?t=N7T8https://www.bilibili.com/video/BV1U4411277i/?spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=7c3bfbf39d037fe80c97234396acc524

讀取圖像

需要處理成灰度圖,因為輸出會根據圖片的尺寸來決定輸出的位置以及窗口的大小,所以我這里自己初始化固定了窗口大小有輸出的位置。

import numpy as np
import cv2# 讀取圖像
image = cv2.imread('input_image.jpg', cv2.IMREAD_GRAYSCALE)# 將灰度圖像調整為固定大小
gray_resized = cv2.resize(image, (500, 400), interpolation=cv2.INTER_NEAREST)# 獲取屏幕尺寸
screen_height, screen_width = 1080, 1920# 計算窗口左上角位置
window_x = int((screen_width - 500) / 2)
window_y = int((screen_height - 400) / 2)# 創建窗口并顯示結果
cv2.namedWindow('GrayImage', cv2.WINDOW_NORMAL)  # 設置窗口大小可調整
cv2.resizeWindow('GrayImage', 500, 400)
cv2.moveWindow('GrayImage', window_x, window_y)
cv2.imshow('GrayImage', gray_resized)
cv2.waitKey(0)
cv2.destroyAllWindows()

降噪(高斯濾波)

高斯濾波_百度百科 (baidu.com)icon-default.png?t=N7T8https://baike.baidu.com/item/%E9%AB%98%E6%96%AF%E6%BB%A4%E6%B3%A2/9032353?fr=ge_ala

OpenCV高斯濾波函數--GaussianBlur()參數說明_gaussianblur參數-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/qq_28126689/article/details/105953157用于平滑圖像以消除噪聲,使得后續的梯度計算更加穩定。

# 高斯濾波
image_blur = cv2.GaussianBlur(image, (5, 5), 1)

梯度計算

計算水平和垂直方向的梯度,因為是向量的形式他這個只有四條線來劃分,假設計算出水平方向是指向0,垂直方向是指向90,他結果就是指向45,如果角度是30也會變成40。

# 計算梯度
gradient_x = cv2.Sobel(image_blur, cv2.CV_64F, 1, 0, ksize=3)
gradient_y = cv2.Sobel(image_blur, cv2.CV_64F, 0, 1, ksize=3)gradient_magnitude = np.sqrt(gradient_x ** 2 + gradient_y ** 2)
gradient_direction = np.arctan2(gradient_y, gradient_x) * 180 / np.pi

非極大值抑制

將梯度圖像中的局部最大值保留,以消除非邊緣像素。對于每個像素,只有梯度方向上的像素值是局部最大值,才會保留,其他像素將被抑制。

就是根據前面梯度的方向,假設他梯度方向是垂直的,如果當前位置上面的元素和下面位置的元素都小于當前位置的元素,則當前位置就是局部最大值,就應該保留下來,反之就會被抑制。

 # 非極大值抑制
gradient_magnitude_suppressed = np.zeros_like(gradient_magnitude)for i in range(1, gradient_magnitude.shape[0] - 1):for j in range(1, gradient_magnitude.shape[1] - 1):angle = gradient_direction[i, j]if (0 <= angle < 22.5) or (157.5 <= angle <= 180) or (-22.5 <= angle < 0) or (-180 <= angle < -157.5):if (gradient_magnitude[i, j] >= gradient_magnitude[i, j + 1]) and (gradient_magnitude[i, j] >= gradient_magnitude[i, j - 1]):gradient_magnitude_suppressed[i, j] = gradient_magnitude[i, j]elif (22.5 <= angle < 67.5) or (-157.5 <= angle < -112.5):if (gradient_magnitude[i, j] >= gradient_magnitude[i - 1, j + 1]) and (gradient_magnitude[i, j] >= gradient_magnitude[i + 1, j - 1]):gradient_magnitude_suppressed[i, j] = gradient_magnitude[i, j]elif (67.5 <= angle < 112.5) or (-112.5 <= angle < -67.5):if (gradient_magnitude[i, j] >= gradient_magnitude[i - 1, j]) and (gradient_magnitude[i, j] >= gradient_magnitude[i + 1, j]):gradient_magnitude_suppressed[i, j] = gradient_magnitude[i, j]elif (112.5 <= angle < 157.5) or (-67.5 <= angle < -22.5):if (gradient_magnitude[i, j] >= gradient_magnitude[i - 1, j - 1]) and (gradient_magnitude[i, j] >= gradient_magnitude[i + 1, j + 1]):gradient_magnitude_suppressed[i, j] = gradient_magnitude[i, j]

雙閾值檢測

像素梯度大于高閾值,則將其標記為強邊緣;如果像素梯度介于低閾值和高閾值之間,則將其標記為弱邊緣;否則,將其標記為非邊緣。

介于兩條線之間的就是可能保留可能淘汰還要看后續的處理,高分數線以上的直接保留,低分數線沒達到的直接淘汰。

# 雙閾值檢測
gradient_magnitude_suppressed_normalized = cv2.normalize(gradient_magnitude_suppressed, None, 0, 255,cv2.NORM_MINMAX, cv2.CV_8U)low_threshold = int(low_threshold)high_threshold = int(high_threshold)strong_edges = (gradient_magnitude_suppressed_normalized >= high_threshold)weak_edges = (gradient_magnitude_suppressed_normalized >= low_threshold) & (gradient_magnitude_suppressed_normalized < high_threshold)

邊緣連接

將弱邊緣連接到強邊緣,以形成完整的邊緣。如果弱邊緣與任何一個強邊緣相連,則將其標記為邊緣;否則,將其標記為非邊緣。

就是畫了兩條分數線,低分數線以下的直接淘汰,高分數以上的直接錄取,如果介于兩條線之間的,看有沒有關系,如果有關系就保留,沒有關系就淘汰。

# 邊緣連接
strong_edges_idx = np.argwhere(strong_edges)
weak_edges_idx = np.argwhere(weak_edges)edge_image = np.zeros_like(gradient_magnitude_suppressed_normalized)
edge_image[strong_edges] = 255for i, j in weak_edges_idx:if np.any(strong_edges[i - 1:i + 2, j - 1:j + 2]):edge_image[i, j] = 255

代碼?

import numpy as np
import cv2def CannyEdgeDetection(image, sigma=1, low_threshold=20, high_threshold=50):# 1. 高斯濾波image_blur = cv2.GaussianBlur(image, (5, 5), sigma)# 2. 計算梯度gradient_x = cv2.Sobel(image_blur, cv2.CV_64F, 1, 0, ksize=3)gradient_y = cv2.Sobel(image_blur, cv2.CV_64F, 0, 1, ksize=3)gradient_magnitude = np.sqrt(gradient_x ** 2 + gradient_y ** 2)gradient_direction = np.arctan2(gradient_y, gradient_x) * 180 / np.pi# 3. 非極大值抑制gradient_magnitude_suppressed = np.zeros_like(gradient_magnitude)for i in range(1, gradient_magnitude.shape[0] - 1):for j in range(1, gradient_magnitude.shape[1] - 1):angle = gradient_direction[i, j]if (0 <= angle < 22.5) or (157.5 <= angle <= 180) or (-22.5 <= angle < 0) or (-180 <= angle < -157.5):if (gradient_magnitude[i, j] >= gradient_magnitude[i, j + 1]) and (gradient_magnitude[i, j] >= gradient_magnitude[i, j - 1]):gradient_magnitude_suppressed[i, j] = gradient_magnitude[i, j]elif (22.5 <= angle < 67.5) or (-157.5 <= angle < -112.5):if (gradient_magnitude[i, j] >= gradient_magnitude[i - 1, j + 1]) and (gradient_magnitude[i, j] >= gradient_magnitude[i + 1, j - 1]):gradient_magnitude_suppressed[i, j] = gradient_magnitude[i, j]elif (67.5 <= angle < 112.5) or (-112.5 <= angle < -67.5):if (gradient_magnitude[i, j] >= gradient_magnitude[i - 1, j]) and (gradient_magnitude[i, j] >= gradient_magnitude[i + 1, j]):gradient_magnitude_suppressed[i, j] = gradient_magnitude[i, j]elif (112.5 <= angle < 157.5) or (-67.5 <= angle < -22.5):if (gradient_magnitude[i, j] >= gradient_magnitude[i - 1, j - 1]) and (gradient_magnitude[i, j] >= gradient_magnitude[i + 1, j + 1]):gradient_magnitude_suppressed[i, j] = gradient_magnitude[i, j]# 4. 雙閾值檢測gradient_magnitude_suppressed_normalized = cv2.normalize(gradient_magnitude_suppressed, None, 0, 255,cv2.NORM_MINMAX, cv2.CV_8U)low_threshold = int(low_threshold)high_threshold = int(high_threshold)strong_edges = (gradient_magnitude_suppressed_normalized >= high_threshold)weak_edges = (gradient_magnitude_suppressed_normalized >= low_threshold) & (gradient_magnitude_suppressed_normalized < high_threshold)# 5. 邊緣連接strong_edges_idx = np.argwhere(strong_edges)weak_edges_idx = np.argwhere(weak_edges)edge_image = np.zeros_like(gradient_magnitude_suppressed_normalized)edge_image[strong_edges] = 255for i, j in weak_edges_idx:if np.any(strong_edges[i - 1:i + 2, j - 1:j + 2]):edge_image[i, j] = 255return edge_image# 讀取圖像
image = cv2.imread('input_image.jpg', cv2.IMREAD_GRAYSCALE)# 使用Canny算子進行邊緣檢測
edges = CannyEdgeDetection(image)# 將邊緣圖像調整為固定大小
edges_resized = cv2.resize(edges, (500, 400), interpolation=cv2.INTER_NEAREST)# 獲取屏幕尺寸
screen_height, screen_width = 1080, 1920# 計算窗口左上角位置
window_x = int((screen_width - 500) / 2)
window_y = int((screen_height - 400) / 2)# 創建窗口并顯示結果
cv2.namedWindow('Canny Edge Detection', cv2.WINDOW_NORMAL)  # 設置窗口大小可調整
cv2.resizeWindow('Canny Edge Detection', 500, 400)
cv2.moveWindow('Canny Edge Detection', window_x, window_y)
cv2.imshow('Canny Edge Detection', edges_resized)
cv2.waitKey(0)
cv2.destroyAllWindows()

?這個代碼是用chatGpt生成的,思路大概是沒錯的,但是不知道能不能對的上,還有就是識別出來的圖像不對,可能很稀疏的幾個點,也可能很密集,這個就需要調整高閾值和低閾值來處理。

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

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

相關文章

基于模糊PID控制器的汽車電磁懸架控制系統simulink建模與仿真

目錄 1.課題概述 2.系統仿真結果 3.核心程序與模型 4.系統原理簡介 5.完整工程文件 1.課題概述 基于模糊PID控制器的汽車電磁懸架控制系統simulink建模與仿真。 2.系統仿真結果 上面的仿真結果是無控制器和LQG的對比&#xff0c;以及有控制器和LQG的對比仿真。 3.核心程…

win10桌面右鍵-新建文件夾-死機-修復

死機->任務管理器->重新啟動 任務管理器&#xff1a;重新啟動“文件資源管理器”或者關閉“文件資源管理器” 快捷鍵&#xff1a;CtrlAltEsc 關閉后桌面黑屏重新啟動&#xff1a;文件->運行新任務->輸入 explorer ->確定 死機-> 事件查看器->排查錯誤 …

Qt串口異步通信案例(從機線程)

文章目錄 串口線程類初始化串口類打開串口并發送數據析構函數 窗口設置窗口函數實現 串口線程類 SlaveThread&#xff08;從機線程&#xff09; 目的&#xff1a;等待并響應來自主機的請求&#xff0c;然后發送預設的響應數據。 關鍵行為&#xff1a;線程啟動后&#xff0c;通過…

STL庫--string

目錄 string的定義 string中內存的訪問 string常用函數實例解析 string的定義 定義string的方式跟基本類型相同&#xff0c;只需要在string后跟上變量名即可&#xff1a; string str; 如果要初始化&#xff0c;可以直接給string類型的變量進行賦值&#xff1a; string s…

Vue3+vite項目中使用mock模擬接口

安裝依賴 分別安裝vite-plugin-mock跟mockjs兩個插件 npm install -D vite-plugin-mock mockjs vite.config.ts中添加配置&#xff0c;主要是紅色標記的配置 注意此處如果配置出錯可能是vite-plugin-mock依賴的版本有問題&#xff0c;重新安裝一下依賴指定版本即可&#xf…

Pytorch環境配置2.0.1+ Cuda11.7

查找cuda、cudnn、Pytorch(GPU)及cuda和NVIDIA顯卡驅動對應關系 查詢可支持的最高cuda版本 nvidia-smi查看支持的cuda的版本 CUDA版本對應表 我的顯卡驅動是Driver Version&#xff1a;535.40.&#xff0c;那么左邊對應的CUDA都可以兼容 右上角為CUDA 版本&#xff0c;可以看…

Ubuntu配置Git

安裝git sudo apt install git 查看是否安裝成功 git --version 配置git 用github上注冊的用戶名和郵箱地址&#xff0c;配置git git config --global user.name "username" git config --global user.email "usernameemail.com" 重啟ubuntu查看…

Collection(一)[集合體系]

說明&#xff1a;Collection代表單列集合&#xff0c;每個元素&#xff08;數據&#xff09;只包含一個值。 Collection集合體系&#xff1a; Collection<E> 接口 (一&#xff09;List<E> 接口 說明&#xff1a;添加的元素是有序、可重復、有索引。 1. ArrayLi…

vue3中的toRaw API

文章目錄 什么是toRaw API&#xff1f;為什么需要toRaw&#xff1f;如何使用toRaw&#xff1f;實際應用場景 這兩天在寫項目的時候&#xff0c;發現了一個之前沒用過的api&#xff0c;于是上網查了一下&#xff0c;發現這個api還是挺常用&#xff0c;所以在這記錄一下 什么是t…

Pytorch實用教程:多分類任務中使用的交叉熵損失函數nn.CrossEntropyLoss

nn.CrossEntropyLoss 在 PyTorch 中是處理多分類問題的常用損失函數,它是兩個函數 nn.LogSoftmax 和 nn.NLLLoss(Negative Log Likelihood Loss)的組合。使用這個損失函數可以直接從模型得到原始的輸出分數(logits),而不需要單獨對輸出進行 Softmax 處理。下面詳細介紹這…

【Postman接口測試】第二節.Postman界面功能介紹(上)

文章目錄 前言一、Postman前言介紹二、Postman界面導航說明三、使用Postman發送第一個請求四、Postman 基礎功能介紹 4.1 常見類型的接口請求 4.1.1 查詢參數的接口請求 4.1.2 表單類型的接口請求 4.1.3 上傳文件的表單請求 4.1.4 JSON 類…

HCIP-Datacom-ARST自選題庫__BGP/MPLS IP VPN簡答【3道題】

1.在BGP/MPLSIPVPN場景中&#xff0c;如果PE設備收到到達同一目的網絡的多條路由時&#xff0c;將按照定的順序選擇最優路由。請將以下內容按照比較順序進行排序。 2.在如圖所示的BGP/MPLSIP VPN網絡中&#xff0c;管理員準備通過Hub-Spoke組網實現H站點對VPM流量的集中管控&am…

C# 配置文件設置詳解

文章目錄 1. 配置文件在 C# 項目中的作用和重要性2. 不同類型的配置文件app.configconfig.exejson 3. 創建和修改配置文件文件位置添加內容修改內容保存和加載 4. 讀取和寫入配置文件app.config 文件讀取config.exe 文件寫入JSON 文件讀寫 5. 示例代碼演示6. 配置文件在安全性方…

【kubernetes】關于k8s集群的污點、容忍、驅逐以及k8s集群故障排查思路

目錄 一、污點(Taint) 1.1污點介紹 1.2污點的組成格式 1.3當前 taint effect 支持如下三個選項&#xff1a; 1.4污點的增刪改查 1.4.1驗證污點的作用——NoExecute 1.4.2驗證污點的作用——NoSchedule 1.4.3 驗證污點的作用——PreferNoSchedule 1.5污點的配置與管理…

防刷發送短信驗證碼接口的五種簡單好用方法絕對夠用

防刷發送短信驗證碼接口的五種簡單好用方法&#xff0c;絕對夠用 前端增加圖形驗證碼&#xff0c;點擊發送按鈕后增加60s倒計時&#xff0c;60s后才可以再次點擊 后端對接口次數校驗&#xff0c;60s內同一電話號碼只能發送一次 // 生成基于電話號碼的重試鎖定鍵 String repeat…

MATLAB增強型鯨魚優化改進算法代碼復現實例

MATLAB增強型鯨魚優化改進算法代碼復現實例 MATLAB增強型鯨魚優化改進算法代碼復現實例

php反序列化學習(1)

1、php面向對象基本概念 類的定義&#xff1a; 類是定義了一件事物的抽象特征&#xff0c;它將數據的形式以及這些數據上的操作封裝住在一起。&#xff08;對象是具有類類型的變量&#xff0c;是對類的實例&#xff09; 構成&#xff1a; 成員變量&#xff08;屬性&#xf…

基于開源項目HAL STM32F4 +DSP庫跑SVPWM開環速度測試

HAL STM32F4 ARM DSP庫跑SVPWM開環速度測試 ?本篇硬件電路和代碼來源于此開源項目&#xff1a;https://github.com/MengYang-x/STM3F401-FOC/tree/main&#x1f4cd;硬件電路和項目介紹&#xff0c;立創開源廣場&#xff1a;https://oshwhub.com/shadow27/tai-yang-neng-wu-re…

走進智慧倉儲:3D可視化工廠園區革新物流新紀元

在快節奏的現代生活中&#xff0c;物流倉儲行業扮演著至關重要的角色。隨著科技的飛速發展&#xff0c;傳統倉儲模式正面臨一場前所未有的變革。今天&#xff0c;就讓我們一起看看3D可視化技術如何為物流行業帶來前所未有的便利與效率。 什么是3D可視化工廠園區&#xff1f; 3…

2024華為OD機試真題-最長子字符串的長度(一)-C++-OD統一考試(C卷D卷)

題目描述 給你一個字符串 s&#xff0c;首尾相連成一個環形&#xff0c;請你在環中找出 o 字符出現了偶數次最長子字符串的長度。 輸入描述 輸入是一個小寫字母組成的字符串 輸出描述 輸出是一個整數 備注 1 ≤ s.length ≤ 500000 s 只包含小寫英文字母 用例1 輸入 alol…