各位程式員,大家好
我目前正在做今年問世的代碼。在第 9 天,我需要找出影像中的像素是否具有相鄰像素的最小值。
我首先非常直觀和粗略地解決了這個問題,但是在看了一會兒之后想知道是否有辦法為 opencv 的filter2D-function 或其他合適的庫定義卷積核, 我可以嘗試在哪里可以將內核定義為函式,這樣我不僅可以執行線性變換,還可以執行其他變換。
在這個特定的例子中,我正在考慮一個內核,它可以判斷中間像素是否具有最低值。也許甚至有一種方法可以使用線性變換來做到這一點,但是我找不到它。
任何幫助表示贊賞。
uj5u.com熱心網友回復:
我自己找到了一個解決方案,只需使用 scipy.ndimage.generic_filter
import numpy as np
from scipy.ndimage import generic_filter
# First define the footprint of the filter you are going to use:
footprint = np.array([[False, True, False],
[True, True, True],
[False, True, False]])
# Then define the filter you want to use:
def lowpoint_kernel(a):
return 0 if a[2] < a[0] and a[2] < a[1] and a[2] < a[3] and a[2] < a[4] else 10
# Get your input here
image = ...
# Pad your image
image = np.pad(image, 1, constant_values=10)
lowpoints = generic_filter(image, lowpoint_kernel, footprint=footprint)
lowpoint_indices = lowpoints == 0
這很可能是一個非常復雜的解決方案,但也許有人會發現這很有用。在此處查看我的完整解決方案。
uj5u.com熱心網友回復:
在 python 中使用 scipy 通用過濾器是個好主意。但據我所知 OpenCV 并沒有提供這樣的方式(自定義函式句柄作為過濾器)。因此,如果您想使用 OpenCV 函式來執行此操作,您可以首先應用侵蝕形態操作(cv::erode)(使用您想要的視窗大小和二進制掩碼)以獲得每個像素鄰域的最小值,然后比較結果使用cv::compare方法或類似方法將影像與原始影像進行對比。
要在最小(侵蝕)中排除中心像素,您可以將自定義的二進制內核傳遞給 cv::erode,其中生成的內核中的中心像素為零。
總而言之,你應該做這樣的事情:
- cv::Mat 內核 = cv::Mat::ones(3,3,CV_8UC1);
內核.at(1, 1)=0; - cv::erode(src, dst_min, 內核);
- cv::compare(src, dst_min, dst, cv::CMP_EQ);
話雖如此,這種方法的唯一限制是最小運算是在 cv::erode 函式中對非零鄰居計算的。如果這不是你想要的效果,你可以給 src 添加一個偏差,然后減去它!
最后但并非最不重要的一點是,如果您正在使用 cpu(而不是 gpu),我建議使用cv::ParallelLoopBody僅通過一次呼叫(記憶體訪問)并行實作所有程序。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/382335.html
上一篇:如何解決“cv2.error:OpenCV(4.5.4):-1:error:(-5:Badargument)infunction'imshow'”
