Caiphas Kain
Caiphas Kain

Reputation: 119

How to convert array to image colour channel in python?

I need to split colour channel of the image (specifically "Cb") in 8x8 blocks in order to modify DCT coefficients and reassemble them back later.

I'm trying to do it using image.extract_patches_2d()

However I can't seem to reassemble the channel

from PIL import Image
from sklearn.feature_extraction import image
import numpy as np

pic = Image.open('lama.png')
pic_size = pic.size
ycbcr = pic.convert('YCbCr')
(y, cb, cr) = ycbcr.split()


acb = np.asarray(cb)
patches = image.extract_patches_2d(acb, (8, 8))
acb2 = image.reconstruct_from_patches_2d(patches, (500,500))
cb_n = Image.fromarray(acb2, 'L')

Even without any changes to the patches reassembled array does not correspond to the original channel:

cb saved as image:

enter image description here

Cb restored from patches (cb_n in code):

enter image description here

So is there something wrong with the code? Or is it impossible to restore colour channel from pathces (blocks) using image.reconstruct_from_patches_2d?

And if so, is there a better way to do what I need?

Thanks for reading, appreciate any help.

Upvotes: 0

Views: 659

Answers (1)

Vivek Kumar
Vivek Kumar

Reputation: 36619

Before calling Image.fromarray() on acb2, make sure to change the dtype to int as it was in the beginning. The image.reconstruct_from_patches_2d changes your picture values to float64, whereas the original values in cb are uint8. This is the only source of error I am getting. Other than that your code is working as expected.

Change your code from:

acb2 = image.reconstruct_from_patches_2d(patches, (500,500))
cb_n = Image.fromarray(acb2, 'L')

to:

acb2 = image.reconstruct_from_patches_2d(patches, (500,500))
#ADD THIS LINE
acb2 = acb2.astype(np.uint8)
cb_n = Image.fromarray(acb2, 'L')

NOTE: (Unrelated to above)

Also make sure you are using correct dimensions in reconstruct_from_patches_2d for the image size. As you have specified (500,500), I am assuming that the width is same as height (500). But in images where height and width are different, Image module will be column-major whereas numpy (and python arrays by default) are row-major. So,

pic_size = pic.size

will report output (Width, Height), But when using in reconstruct_from_patches_2d, use (Height, Width).

Upvotes: 2

Related Questions