Bijay Regmi
Bijay Regmi

Reputation: 1288

Create a non rectangular image from a rectangular image using python

I have several 700x400 images which look like image belowenter image description here

They consist of two regions, one represented by blue and another represented by green. These regions are separated by a line. A XML file contains 700 co-ordinates alone y-axis for the line for all images (so about 60 arrays) separating these regions which looks like this:

<?xml version="1.0" encoding="utf-8"?> 
<Data>
<Image>
<ImageUrl> file:///Data/1.tif </ImageUrl>
<Array> 150 144 169 199 199 200 210 ..... 344 </Array>
</Image>
<Image>
<ImageUrl> file:///Data/2.tif </ImageUrl>
<Array> 150 144 169 199 199 200 210 ..... 344 </Array>
</Image>
.
.
.
</Data>

Now I want to cut the image ABCD along this line and only have the green region. I have seen this but can not get it to work. I have tried :

import xml.etree.ElementTree as ET
import cv2, numpy as np
tree = ET.parse("image.xml")
segArray = tree.findall(".//Image/Array")
arrayList = []
for i in range (0,len(segArray)-1):
xa = segArray[i].text.split(" ")
        arrayList.append(xa)
arrayList = np.array(arrayList)

arrayList stores of arrays but now I can not think of a way to use these arrays to cut the image like I want to.

Upvotes: 1

Views: 627

Answers (1)

Mark Setchell
Mark Setchell

Reputation: 207540

A question about image processing with neither representative image nor data is rather hard to answer, but I'll guess you want to make the top part of some unspecified image transparent down to a certain distance from the top according to some form of XML.

So, I'll start with paddington as my input image and a sine wave as my XML and assume you can adapt to whatever it is you are trying to do:

enter image description here

And code like this with PIL/Pillow:

#!/bin/env python3

from math import sin,cos
import numpy as np
from PIL import Image

# Create a new alpha mask, initially all white, that makes parts of image transparent
w, h = 700, 400
alpha = np.ones((h,w), dtype=np.uint8)*255

# Draw a vertical black line of length "l" from top downwards at each column position across image
for col in range(w):
    # Length of line is given by a sine wave
    l = abs(int(sin(col/30)*h/3))
    alpha[0:l, col] = 0


# Now open our image and push that alpha layer into it
im = Image.open('image.png').convert('RGB')

im.putalpha(Image.fromarray(alpha))
im.save('result.png')

Result

enter image description here

The alpha layer I created looks like this, with a red border added so you can see its extent on StackOverflow's white background:

enter image description here

Upvotes: 4

Related Questions