0

I'm trying to accomplish a basic image processing. Here is my algorithm :

Find n., n+1., n+2. pixel's RGB values in a row and create a new image from these values.

enter image description here

I'm taking first pixel's red value,second pixel's green value and third pixel's blue value and create pixel. This operation continue for every row in image.

Here is my example code in python :

import glob
import ntpath

import numpy
from PIL import Image

images = glob.glob('balls/*.png')
data_compressed = numpy.zeros((540, 2560, 3), dtype=numpy.uint8)
for image_file in images:

    print(f'Processing [{image_file}]')
    image = Image.open(image_file)
    data = numpy.loadasarray(image)

    for i in range(0, 2559):
        for j in range(0, 539):
            pix_x = j * 3 + 1
            red = data[pix_x - 1, i][0]
            green = data[pix_x, i][1]
            blue = data[pix_x + 1, i][2]
            data_compressed[j, i] = [red, green, blue]

    im = Image.fromarray(data_compressed)
    image_name = ntpath.basename(image_file)
    im.save(f'export/{image_name}')

My input and output images are in RGB format. My code is taking 5 second for every image. I'm open for any idea to optimization this task. I can use c++ or any other languages if necessary.

2
  • Are all pixels greyscale or can they be any color? Commented Aug 13, 2020 at 9:08
  • can be any color Commented Aug 13, 2020 at 10:58

3 Answers 3

1
data_compressed = np.concatenate((
    np.expand_dims(data[0:-2][:,:,0], axis=2),
    np.expand_dims(data[1:-1][:,:,1], axis=2),
    np.expand_dims(data[2:][:,:,2], axis=2)), axis=2)
  1. Image1 : Original image
  2. Image2: Original image shifted by one pixel
  3. Image3: Original image shifted by two pixel
  4. Take channel 0 of Image1, channel 1 of Image2 and channel 3 of Image3 concatenate.

Sample

import numpy as np
from PIL import Image
import matplotlib.pyplot as plt

image = Image.open("Lenna.png")
data = numpy.asarray(image)

data_compressed = np.concatenate((
    np.expand_dims(data[0:-2][:,:,0], axis=2),
    np.expand_dims(data[1:-1][:,:,1], axis=2),
    np.expand_dims(data[2:][:,:,2], axis=2)), axis=2)

new_image = Image.fromarray(data_compressed)

If you want a stride over 3 pixels for calculating the next pixel again then you can use numpy slicing

new_image = Image.fromarray(data_compressed[:, ::3])

Original Image:

enter image description here

Transformed Image with 3 stride:

enter image description here

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. It's much more faster than my code but it's working on all image. My input image is : 2560 x 1620 and final image is 2560 x 540. So it's need to be work on 1 axis not two. Is it possible to do in 1 axis.
thanks it's worked like a charm. my old code was 5 second per picture now 0.12 second per picture.
exported image is loosing 2 pixel in one dimension. Did you notice that ? Example image 220x220 => final image 74 x 218
0

Well if are only looking for a speed up you should take a look at the module Cython. It lets you specify the type of different variables and then compile the script to functioning c code. This can often lead to great improvements when it comes to time complexity.

Comments

0

With plain python there's only so much you can do. Here is a small optimization which can help a bit since it will allocate less memory. Otherwise I would look at Cython/Numba as said previously or using other languages.

data_compressed[j, i, 0] = data[pix_x - 1, i][0]
data_compressed[j, i, 1] = data[pix_x, i][1]
data_compressed[j, i, 2] = data[pix_x + 1, i][2]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.