如何半色调黑白照片?

时间:2017-12-15 07:56:17

标签: python image numpy

我希望将图片划分为相同的大正方形并测量平均灰度级别,并将其替换为blob,即半色调。这段代码给了我一张照片,但看起来并不正确。什么想法可能是错的?

im = scipy.misc.imread("uggla.tif")

def halftoning(im):
    im = im.astype('float64')
    width,height = im.shape
    halftone_pic = np.zeros((width, height))
    for x in range(width):
        for y in range(height):
            floating_matrix = im[x:x + 1, y:y + 1]
            sum = np.sum(floating_matrix)
            mean = np.mean(sum)
            round = (mean > 128) * 255
            halftone_pic[x,y] = round
    fig, ax = plt.subplots(1,2)
    ax[0].imshow(im, cmap="gray")
    ax[1].imshow(halftone_pic, cmap="gray")
    plt.show()

1 个答案:

答案 0 :(得分:2)

这是满足你想要的东西。这是对related question

的回答中代码的改编
from PIL import Image, ImageDraw, ImageStat

# Adaption of answer https://stackoverflow.com/a/10575940/355230
def halftone(img, sample, scale, angle=45):
    ''' Returns a halftone image created from the given input image "img".
        "sample" (in pixels), determines the sample box size from the original
        image. The maximum output dot diameter is given by "sample" * "scale"
        (which is also the number of possible dot sizes). So "sample" == 1 will
        preserve the original image resolution, but "scale" must be > 1 to allow
        variations in dot size.
    '''
    img_grey = img.convert('L')  # Convert to greyscale.
    channel = img_grey.split()[0]  # Get grey pixels.
    channel = channel.rotate(angle, expand=1)
    size = channel.size[0]*scale, channel.size[1]*scale

    bitmap = Image.new('1', size)
    draw = ImageDraw.Draw(bitmap)

    for x in range(0, channel.size[0], sample):
        for y in range(0, channel.size[1], sample):
            box = channel.crop((x, y, x+sample, y+sample))
            mean = ImageStat.Stat(box).mean[0]
            diameter = (mean/255) ** 0.5
            edge = 0.5 * (1-diameter)
            x_pos, y_pos = (x+edge) * scale, (y+edge) * scale
            box_edge = sample * diameter * scale
            draw.ellipse((x_pos, y_pos, x_pos+box_edge, y_pos+box_edge),
                         fill=255)

    bitmap = bitmap.rotate(-angle, expand=1)
    width_half, height_half = bitmap.size
    xx = (width_half - img.size[0]*scale) / 2
    yy = (height_half - img.size[1]*scale) / 2
    bitmap = bitmap.crop((xx, yy, xx + img.size[0]*scale,
                                  yy + img.size[1]*scale))
    return Image.merge('1', [bitmap])

# Sample usage

img = Image.open('uggla.tif')
img_ht = halftone(img, 8, 1)
img_ht.show()

以下是将其用作输入图像的结果:

input image

产生了半色调结果:

Halftoned result