开发者

How do I deinterlace an image in Python?

开发者 https://www.devze.com 2023-04-09 15:14 出处:网络
Let\'s assume the image is stored as a png file and I need to drop every odd line and resize the resu开发者_C百科lt horizontally to 50% in order to keep the aspect ratio.

Let's assume the image is stored as a png file and I need to drop every odd line and resize the resu开发者_C百科lt horizontally to 50% in order to keep the aspect ratio.

The result must have 50% of the resolution of the original image.

It will not be enough to recommend an existing image library, like PIL, I would like to see some working code.

UPDATE - Even if the question received a correct answer, I want to warn others that PIL is not in a great shape, the project website was not updated in months, there is no link to a bug traker and the list activity is quite low. I was surprised to discover that a simple BMP file saved with Paint was not loaded by PIL.


Is it essential to keep every even line (in fact, define "even" - are you counting from 1 or 0 as the first row of the image?)

If you don't mind which rows are dropped, use PIL:

from PIL import Image
img=Image.open("file.png")
size=list(img.size)
size[0] /= 2
size[1] /= 2
downsized=img.resize(size, Image.NEAREST) # NEAREST drops the lines
downsized.save("file_small.png")


I recently wanted to deinterlace some stereo images, extracting the images for the left and right eye. For that I wrote:

from PIL import Image

def deinterlace_file(input_file, output_format_str, row_names=('Left', 'Right')):
    print("Deinterlacing {}".format(input_file))
    source = Image.open(input_file)
    source.load()
    dim = source.size

    scaled_size1 = (math.floor(dim[0]), math.floor(dim[1]/2) + 1)
    scaled_size2 = (math.floor(dim[0]/2), math.floor(dim[1]/2) + 1)

    top = Image.new(source.mode, scaled_size1)
    top_pixels = top.load()
    other = Image.new(source.mode, scaled_size1)
    other_pixels = other.load()
    for row in range(dim[1]):
        for col in range(dim[0]):
            pixel = source.getpixel((col, row))
            row_int = math.floor(row / 2)
            if row % 2:
                top_pixels[col, row_int] = pixel
            else:
                other_pixels[col, row_int] = pixel


    top_final = top.resize(scaled_size2, Image.NEAREST) # Downsize to maintain aspect ratio
    other_final = other.resize(scaled_size2, Image.NEAREST) # Downsize to maintain aspect ratio
    top_final.save(output_format_str.format(row_names[0]))
    other_final.save(output_format_str.format(row_names[1]))

output_format_str should be something like: "filename-{}.png" where the {} will be replaced with the row name.

Note that it ends up with the image being half of it's original size. If you don't want this you can twiddle the last scaling step

It's not the fastest operation as it goes through pixel by pixel, but I could not see an easy way to extract rows from an image.

0

精彩评论

暂无评论...
验证码 换一张
取 消