【问题标题】:Image outline using python/PIL使用 python/PIL 的图像轮廓
【发布时间】:2021-04-19 05:57:55
【问题描述】:

我有一张苹果的彩色照片,如何用 python/PIL 只显示它的轮廓(内白,黑底)?

【问题讨论】:

  • 包括一些预期输入的示例图像。

标签: python-imaging-library


【解决方案1】:

这样的事情应该可以工作。

from PIL import Image, ImageFilter

image = Image.open('your_image.png')
image = image.filter(ImageFilter.FIND_EDGES)
image.save('new_name.png') 

如果这不能为您提供您正在寻找的结果,那么您尝试使用 PIL 和 Python 和其他库实现 Prewitt 边缘检测、Sobel 边缘检测或 Canny 边缘检测,请参阅相关的question 和以下example .

如果您尝试进行粒子检测/分析而不仅仅是边缘检测,您可以尝试使用py4ij 来调用您链接的 ImageJ 方法以获得相同的结果,或者尝试另一个粒子分析 Python 库 @987654324 @ 或者,您可以使用 PIL、S​​ciPy 和 NumPy 编写粒子检测算法。

【讨论】:

  • 嗨,照片是彩色的,即使我对它们进行灰度化并运行过滤器,它也不能正常工作,因为我只想要苹果形状的轮廓,这可能吗?它类似于 rsbweb.nih.gov/ij/docs/pdfs/examples.pdf 中描述的 imageJ 方法。谢谢
  • @Appleman1234,非常感谢您参考我的帖子。嘿,您可以导入精明的边缘检测模块并运行它以单独查找边缘。输出将是一个 numpy ndarray,但您可以使用 im = Image.fromarray(imarray) 转换为 PIL 图像
  • @Appleman 是否可以根据 FIND_EDGES 将图像拆分为组件?
【解决方案2】:

如果你的物体和背景有相当好的对比度

from PIL import Image
image = Image.open(your_image_file)
mask=image.convert("L")
th=150 # the value has to be adjusted for an image of interest 
mask = mask.point(lambda i: i < th and 255)
mask.save(file_where_to_save_result)

如果其中一种(3 种颜色)具有较高的对比度,您可以将图像分割成条带,而不是将其转换为灰度。

如果图像或背景相当复杂,则需要更复杂的处理

【讨论】:

    【解决方案3】:

    Apple vs Lines 您只需使用 PIL 和 Python,只需不到 200 行代码即可完成。使用库中的精明边缘检测会更容易。
    这是步骤。转换为灰度以获得流明。使用内核图像处理使用 Sobel 检测边缘。使用从 Sobel 获得的幅度和斜率对边缘进行细化。

    from PIL import Image
    import math
    
    
    def one_to_two_dimension_array(list_,columns):
        #use list slice
        return [ list_[i:i+columns] for i in range(0, len(list_),columns) ] 
    
    def flatten_matrix(matrix):
        return [val for sublist in matrix for val in sublist]
    
    def matrix_convole(matrix, kernel_matrix, multiplier):
        return_list=[]
        return_matrix=[]
    
        border=(len(kernel_matrix) - 1) / 2;border=int(border)
        center_kernel_pos=border
        for matrix_row in range( len( matrix )):
            for matrix_col in range(len( matrix[matrix_row] ) ):
                accumulator = 0
                if (matrix_row - border)<0 or \
                (matrix_col-border)< 0 or \
                (matrix_row+border) > (len( matrix )-border) or \
                (matrix_col+border) > (len( matrix[matrix_row] )-border):
                    return_list.append(matrix[matrix_row][matrix_col])
                    continue
                for kernel_row in range(len (kernel_matrix) ):
                    for kernel_col in range(len (kernel_matrix[kernel_row]) ):      
    
                        relative_row= kernel_row - center_kernel_pos
                        relative_col= kernel_col - center_kernel_pos
                        kernel = kernel_matrix[kernel_row][kernel_col]
                        pixel = matrix [matrix_row + relative_row] [matrix_col + relative_col]
                        accumulator += pixel * kernel
                return_list.append(accumulator* multiplier )
        return_matrix = one_to_two_dimension_array( return_list, len( matrix[0] ) )
        return return_matrix
                
    def canny_round_degree(deg):
        #0, 22.5, 45, 67.5, 90, 112.5, 135, 157.5, 180
    
        if deg >= 0 and deg <= 22.5:
            return 0
        elif deg >= 22.5 and deg <= 67.5:
            return 45
        elif deg > 67.5 and deg <=112.5:
            return 90
        elif deg > 112.5 and deg <=157.5:
            return 135
        elif deg >= 157.5 and deg <= 180:
            return 0
    
        if deg <= 0 and deg >= -22.5:
            return 0
        elif deg <= -22.5 and deg >= -67.5:
            return 135
        elif deg < -67.5 and deg >= -112.5:
            return 90
        elif deg < -112.5 and deg >= -157.5:
            return 45
        elif deg <= -157.5 and deg >= -180:
            return 0
    
    image_path='apple.jpg'
    gaussian_5x5_kernel=[[2,4,5,4,2],[4,9,12,9,4],[5,12,15,12,5],[4,9,12,9,4],[2,4,5,4,2]] #multiplier 1/159
    sobel_kernel_gx=[[-1,0,1],[-2,0,2],[-1,0,1]]
    sobel_kernel_gy=[[-1,-2,-1],[0,0,0],[1,2,1]] 
    im_list=list(Image.open(image_path).convert('L').getdata(0)) #grayscale, get first channel
    im_width=Image.open(image_path).width
    im_height=Image.open(image_path).height
    im_matrix = one_to_two_dimension_array(im_list, im_width)
    
    im_matrix_blur=matrix_convole(im_matrix,gaussian_5x5_kernel, 1/159)
    
    sobel_gx_matrix=matrix_convole(im_matrix_blur,sobel_kernel_gx, 1)
    sobel_gy_matrix=matrix_convole(im_matrix_blur,sobel_kernel_gy, 1)
    
    sobel_gy_list=flatten_matrix(sobel_gy_matrix) 
    sobel_gx_list=flatten_matrix(sobel_gx_matrix) 
    
    sobel_g_magnitude_list = [math.hypot(gy,gx) for gx,gy in zip(sobel_gx_list,sobel_gy_list)]
    
    
    sobel_g_angle_list = [ canny_round_degree(math.degrees(math.atan2(gy,gx))) for gx,gy in zip(sobel_gx_list,sobel_gy_list)]
    
    sobel_g_angle_matrix = one_to_two_dimension_array(sobel_g_angle_list, im_width)
    sobel_g_magnitude_matrix = one_to_two_dimension_array(sobel_g_magnitude_list, im_width)
    suppression_list = []
    for s_row in range( len( sobel_g_angle_matrix)):
        for s_col in range(len( sobel_g_angle_matrix[s_row] ) ):
            if (s_row - 1)<0 or \
                (s_col-1)< 0 or \
                (s_row+1) > (len( sobel_g_angle_matrix )-1) or \
                (s_col+1) > (len( sobel_g_angle_matrix[s_row] )-1):
                suppression_list.append(0)
                continue
        
            magnitude_in_question = sobel_g_magnitude_matrix[s_row][s_col]
            #thresholding magnitude continue, arbitrary 129
            if magnitude_in_question < 36:
                suppression_list.append(0)
                continue    
    
            angle_in_question = sobel_g_angle_matrix[s_row][s_col]
    
            east_magnitude = sobel_g_magnitude_matrix[s_row][s_col-1]
            west_magnitude = sobel_g_magnitude_matrix[s_row][s_col+1]
            north_magnitude = sobel_g_magnitude_matrix[s_row-1][s_col]
            south_magnitude = sobel_g_magnitude_matrix[s_row+1][s_col]
            north_east_magnitude = sobel_g_magnitude_matrix[s_row-1][s_col-1]
            north_west_magnitude = sobel_g_magnitude_matrix[s_row-1][s_col+1]
            south_east_magnitude = sobel_g_magnitude_matrix[s_row+1][s_col-1]
            south_west_magnitude = sobel_g_magnitude_matrix[s_row+1][s_col+1]       
            if angle_in_question == 0 and magnitude_in_question > east_magnitude \
                and magnitude_in_question > west_magnitude:
                suppression_list.append(1)  
            elif angle_in_question == 90 and magnitude_in_question > north_magnitude \
                and magnitude_in_question > south_magnitude:
                suppression_list.append(1)  
            elif angle_in_question == 135 and magnitude_in_question > north_west_magnitude \
                and magnitude_in_question > south_east_magnitude:
                suppression_list.append(1)  
            elif angle_in_question == 45 and magnitude_in_question > north_east_magnitude \
                and magnitude_in_question > south_west_magnitude:
                suppression_list.append(1)  
            else:
                suppression_list.append(0)  
                
    
    new_img = Image.new('1', (im_width,im_height)) #bw=1;grayscale =L
    new_img.putdata( suppression_list )
    new_img.save('apple-lines.png', 'PNG')
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-15
      • 2021-01-05
      • 1970-01-01
      • 2015-04-24
      • 2020-10-25
      • 2017-10-07
      • 2021-12-23
      • 2019-12-06
      相关资源
      最近更新 更多