所以我試圖重現一個很酷的過濾器,我在 Python cv2 的 C# (emgucv) 中做了一段時間。盡管我希望它不會很順利。這些程式假設突出邊緣并用看起來很酷的漸變為它們著色。
C# 中的代碼:
{
Image<Gray, byte> gray= imgColored.Convert<Gray, byte>();
Image<Gray, float> photo_dx = gray.Sobel(1, 0, 3);
Image<Gray, float> photo_dy = gray.Sobel(0, 1, 3);
Image<Gray, float> photo_grad = new Image<Gray, float>(gray.Size);
Image<Gray, float> photo_angle = new Image<Gray, float>(gray.Size);
CvInvoke.CartToPolar(photo_dx, photo_dy, photo_grad, photo_angle, true);
Image<Hsv, float> coloredEdges = gray.Convert<Hsv, float>();
for (int j = 0; j < coloredEdges.Cols; j )
for (int i = 0; i < coloredEdges.Rows; i )
{
Hsv pix = coloredEdges[i, j];
pix.Hue = photo_angle[i, j].Intensity;
pix.Satuation = 1;
pix.Value = photo_grad[i, j].Intensity;
coloredEdges[i, j] = pix;
}
coloredEdges.Save("test.jpg");
}
Python中的代碼:
def LSD_ify(image, mag, angle):
image = image = image.astype(np.float64)
height, width, depth = image.shape
for x in range(0, height):
for y in range(0, width):
image[x, y, 0] = angle[x, y]
image[x, y, 1] = 1
image[x, y, 2] = mag[x, y]
return image
def main():
image = plt.imread(str(sys.argv[1]))
gray_image = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
g2bgr = cv.cvtColor(gray_image, cv.COLOR_GRAY2BGR) #cv2 cant convert gray to HSV directly, so i had to convert back to colored and finally to HSV
gx = cv.Sobel(gray_image, cv.CV_64F, 1, 0, ksize = 3)
gy = cv.Sobel(gray_image, cv.CV_64F, 0, 1, ksize = 3)
mag, angle = cv.cartToPolar(gx, gy, angleInDegrees = True)
hsv_image = cv.cvtColor(g2bgr, cv.COLOR_BGR2HSV)
lsd = LSD_ify(hsv_image, mag, angle)
cv.imwrite("test.jpg", lsd)
if __name__ == "__main__":
main()
代碼大部分是相同的(我認為?),但是它們產生的結果是不同的。輸入影像:

C#程式:

Python腳本:

有沒有人知道我必須做什么才能在 Python 中獲得相同的結果?我不確定 Python 的后臺是如何作業的。
uj5u.com熱心網友回復:
我認為這就是您在 Python/OpenCV 中嘗試做的事情。Python HSV 色調限制在 0 到 180 的范圍內,因此您的角度需要縮放到該范圍。同樣,幅度大于 255,也需要縮放到 0 到 255 的范圍。您想要的飽和度將是一個常數 255。我使用 Skimage 進行縮放。我已經在各個地方列印了形狀以及最小值和最大值,以向您展示這些問題。
我相信程序如下:
- 讀取輸入
- 將其轉換為灰色
- 獲取 Sobel x 和 y 導數
- 計算導數的大小和角度,并將 mag 縮放到 0 到 255 的范圍和角度到 0 到 180 的范圍
- 將角度、幅度和幅度合并為 3 通道影像,就好像 HSV 先有角度,然后是幅度。
- 將第二個通道(通道 1)替換為 255 以獲得飽和度
- 將此 HSV 影像轉換為 BGR 作為結果
- 保存結果
輸入:

import cv2
import numpy as np
import skimage.exposure as exposure
# read the image
img = cv2.imread('rabbit.jpg')
# convert to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# apply sobel derivatives
sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)
print(sobelx.shape, np.amin(sobelx), np.amax(sobelx))
print(sobely.shape, np.amin(sobely), np.amax(sobely))
print("")
# get magnitude and angle
mag, angle = cv2.cartToPolar(sobelx, sobely, angleInDegrees = True)
print(mag.shape, np.amin(mag), np.amax(mag))
print(angle.shape, np.amin(angle), np.amax(angle))
print("")
# normalize mag to range 0 to 255 and angle to range 0 to 180
mag = exposure.rescale_intensity(mag, in_range='image', out_range=(0,255)).clip(0,255).astype(np.uint8)
angle = exposure.rescale_intensity(angle, in_range='image', out_range=(0,180)).clip(0,180).astype(np.uint8)
print(mag.shape, np.amin(mag), np.amax(mag))
print(angle.shape, np.amin(angle), np.amax(angle))
# combine channels as if hsv where angle becomes the hue and mag becomes the value. (saturation is not important since it will be replace by 255)
hsv = cv2.merge([angle, mag, mag])
hsv[:,:,1] = 255
# convert hsv to bgr
result = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
# save results
cv2.imwrite('rabbit_color_edges.jpg', result)
# show result
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

添加
如果我通過將“out_range”加倍來縮放幅度(或灰度):
mag = exposure.rescale_intensity(mag, in_range='image', out_range=(0,255)).clip(0,255).astype(np.uint8)
到
mag = exposure.rescale_intensity(mag, in_range='image', out_range=(0,510)).clip(0,255).astype(np.uint8)
然后我非常接近你的結果:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/408485.html
標籤:
上一篇:使用opencv-rust做翻轉
