代码之家  ›  专栏  ›  技术社区  ›  Wizard

将颜色应用于渐变方向

  •  0
  • Wizard  · 技术社区  · 6 年前

    参考 this post,当将颜色的梯度方向的程度硬编码到图像上时,强度发生变化的地方应该着色,没有变化的地方应该是黑色的。

    我不知道这是如何在那个职位上执行的。因为所有的度数值都指定了一种颜色,所以对图像中的所有像素进行着色而不留下任何黑色。

    我的代码如下:

    # where gray_blur is a grayscale image of dimension 512 by 512
    
    # 3x3 sobel filters for edge detection
    sobel_x = np.array([[ -1, 0, 1], 
                       [ -2, 0, 2], 
                       [ -1, 0, 1]])
    
    
    sobel_y = np.array([[ -1, -2, -1], 
                       [ 0, 0, 0], 
                       [ 1, 2, 1]])
    
    
    # Filter the orginal and blurred grayscale images using filter2D
    filtered = cv2.filter2D(gray_noise, cv2.CV_32F, sobel_x)
    
    filtered_blurred_x = cv2.filter2D(gray_blur, cv2.CV_32F, sobel_x)  
    filtered_blurred_y = cv2.filter2D(gray_blur, cv2.CV_32F, sobel_y) 
    
    # Compute the orientation of the image
    orien = cv2.phase(filtered_blurred_x, filtered_blurred_y, angleInDegrees=True)
    
    image_map = np.zeros((orien.shape[0], orien.shape[1], 3), dtype=np.int16)
    
    # Define RGB colours
    red = np.array([255, 0, 0])
    cyan = np.array([0, 255, 255])
    green = np.array([0, 255, 0])
    yellow = np.array([255, 255, 0])
    
    # Set colours corresponding to angles
    for i in range(0, image_map.shape[0]):
        for j in range(0, image_map.shape[1]):
            if orien[i][j] < 90.0:
                image_map[i, j, :] = red
            elif orien[i][j] >= 90.0 and orien[i][j] < 180.0:
                image_map[i, j, :] = cyan
            elif orien[i][j] >= 180.0 and orien[i][j] < 270.0:
                image_map[i, j, :] = green
            elif orien[i][j] >= 270.0 and orien[i][j] < 360.0:
                image_map[i, j, :] = yellow
    
    # Display gradient orientation
    f, ax1 = plt.subplots(1, 1, figsize=(20,10))
    
    ax1.set_title('gradient orientation')
    ax1.imshow(image_map)
    

    我的代码生成左边的输出,而我认为正确的表示应该是右边的图像:

    Orientation

    我想我遗漏了一些关于将每个像素硬编码为这些颜色之一的内容。

    1 回复  |  直到 6 年前
        1
  •  2
  •   api55    6 年前

    你缺少的是数量级的阈值。你可以知道它是否有任何相关的方向。。。在某种程度上,它是一种对方向进行过滤的方法,只给出响应强的方向,在大多数情况下,这些方向是边缘。

    如果这一步没有完成,那么每一个像素至少有一个4种颜色,我认为这不是你想要的。

    下面是一个示例代码来说明我的观点:

    import numpy as np
    import cv2
    
    # reads the image
    img = cv2.imread("lena.png", 0
    
    # sobel derivatives
    derivX = cv2.Sobel(img, cv2.CV_32F, 1, 0)
    derivY = cv2.Sobel(img, cv2.CV_32F, 0, 1)
    
    # orientation and magnitude
    orien = cv2.phase(derivX, derivY, angleInDegrees=True)
    mag = cv2.magnitude(derivX, derivY)
    
    # thresholding of the magnitude values, play with the thresh value adjust it too your liking
    thresh = 50
    _, mask = cv2.threshold(mag, thresh, 255, cv2.THRESH_BINARY)
    
    # I used OpenCV imshow instead of matplotlib, so the colors are in BGR (use yours)
    red = np.array([0, 0, 255])
    cyan = np.array([255, 255, 0])
    green = np.array([0, 255, 0])
    yellow = np.array([0, 255, 255])
    
    # for the same reason I use np.uint8
    image_map = np.zeros((orien.shape[0], orien.shape[1], 3), dtype=np.uint8)
    
    # setting the colors, maybe there is a better way, my numpy skills are rusty
    # it checks that magnitude is above the threshold and that the orientation is in range
    image_map[ (mask == 255) & (orien < 90) ] = red
    image_map[(mask == 255) & (orien > 90) & (orien < 180)] = cyan
    image_map[(mask == 255) & (orien > 180) & (orien < 270)] = green
    image_map[(mask == 255) & (orien > 270)] = yellow
    
    # just for showing it with opencv, replace it with matplotlib if you prefer
    cv2.imshow("frame", image_map)
    cv2.waitKey(0)
    

    结果是:

    enter image description here