Amrit Das
Amrit Das

Reputation: 35

Image Distribution

I actually was working on a image distribution project, i am new to image processing. My aim was to write a program to distribute it into 6 parts each having equal pixel data. I wrote the below mentioned code.

    from PIL import Image
    import cv2
    im = Image.open('grey.jpg')
    im_grey = im.convert('LA')

    width,height = im.size
    line = []

    j,h,total,c=0,0,0,0

    for i in range(0,width):    
        for j in range(0,height):
            total += im_grey.getpixel((i,j))[0]
            h += im_grey.getpixel((i,j))[0]
        c += 1
        if c==5:
            line.append(h)
            c = 0
            print "LINE : " + str(i) + "=" + str(h)
            h = 0

    average_pix = total/6
    print total
    i,m,j,=0,0,0,
    def image_distribution():
        global i,m,j,d,average_pix,image
        while i<=len(line)-1:

            j=j+ line[i]

            if j>=average_pix :
                img=im.crop((0,m,width,i*5))
                img.save("Images/"+"image"+str(i)+".jpg")
                m = i*5
                j=0

            i+=1
    image_distribution() 

The code seems to work, but not properly, so I would really appreciate if someone can help me with the script or any better script for the same purpose. P.S. I am also trying to write a time efficient program. Thanks and yes the image "grey.jpg" is a greyscale image.

Upvotes: 1

Views: 853

Answers (1)

rayryeng
rayryeng

Reputation: 104555

Going with our discussion, you would like to decompose your image into 6 separate images. The total summed intensity for the 6 separate images is equal. As you don't have a preference for how to decompose the images, I'll be decomposing the image column-wise. Therefore, each image will have the same number of rows, but the number of columns will be different such that each decomposed image will have more or less the same intensity sum. Take note however that we may not get exactly the same sum for each image due to the very nature of this algorithm, but the differences should hopefully be minimal.

Because you're able to use any module in Python, I would recommend using NumPy but you can still use Pillow to read in the original image. Convert the image into a NumPy array first so that we can fully use the NumPy array methods to do what you want.

The process that I will follow is quite simple.

  1. Find the total summation of all intensity values in the image and divide this by 6 to determine the "split point".
  2. Starting with the first column, find the column sum, then move to the next column and accumulate.
  3. When we have a cumulative column sum that surpasses the split point, save this image, reset the cumulative column sum and start the process again from this point.
  4. Repeat until we get to the end of the image.
  5. Take the extracted images and save them to file.

Without further ado:

from PIL import Image
import numpy as np

# Open up the image and convert to grayscale
im = Image.open('grey.jpg').convert('L')

# Convert to a numpy array, convert to floating point for precision
im = np.asarray(im, dtype=np.float)

# Determine the total sum of the pixels
total_sum = im.sum()

# Determine the split point
split_point = int(total_sum / 6)

# Store the images here
data = []

# Counts up how many images we've made so far
count = 0

# Records the column sum
column_sum = 0

# Records beginning coordinate of the split image
x = 0

# Until we've exhausted all of the data...
# Go through each column and determine the cumulative sums
for i in range(im.shape[1]):
    column_sum += np.sum(im[:, i])

    # If the column sum has passed the threshold
    if column_sum >= split_point:
        # Get the image and save it
        data.append(im[:, x : i + 1])

        # Update the variables for the next round
        x = i + 1
        column_sum = 0
        count += 1

    # If we have reached the 5th image, just use the rest
    # of the image data as the last image
    if count == 5:
        data.append(im[:, x:])
        break

# Save the images now
for (i, split_img) in enumerate(data):
    pimg = Image.fromarray(split_img.astype(np.uint8))
    pimg.save("image%d.jpg" % (i + 1))            

Take note that the intricacy at the end is so that we convert the split images into uint8 first, then create a Pillow image, then save this to file. The images are labelled such that they are imagex.jpg where x is a number from 1 to 6.

Upvotes: 1

Related Questions