python cv2 和 C# emgu cv 中的着色边

Coloring edges in python cv2 and C# emgu cv

所以我试图在 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.

中的后台运行情况

我认为这就是您在 Python/OpenCV 中尝试做的事情。 Python HSV 色调限制在 0 到 180 的范围内,因此您的角度需要缩放到该范围。同样,幅度大于 255,也需要缩放到 0 到 255 的范围内。您想要的饱和度将是一个常数 255。我使用 Skimage 进行缩放。我已经在各个地方打印出形状和最小值和最大值来向您展示这些问题。

我认为过程如下:

  • 读取输入
  • 将其转换为灰色
  • 获取 Sobel x 和 y 导数
  • 计算导数的大小和角度,并将 mag 缩放到 0 到 255 的范围,将 angle 缩放到 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)

那我就很接近你的结果了: