0

I would like to split an image into triangle shaped tiles (equilateral) . I have tried to generate the coordinates of a triangle using the function from https://alexwlchan.net/2016/10/tiling-the-plane-with-pillow/. My code:

#import opencv 
import math 
image_path="/content/newspaper-icon-in-transparent-style-news-on-vector-25591681.jpg"

#Create Triangles
# https://alexwlchan.net/2016/10/tiling-the-plane-with-pillow/
#A horrizontal offset is added to ensure that images line up
#https://stackoverflow.com/questions/22588074/polygon-crop-clip-using-python-pil
def generate_coordinates_for_unit_triangles(image_width,image_height):
     image_width=50;
     image_height=50;
     h=math.sin(math.pi/3)
     for x in range(image_width):
        for y in range(int(image_height / h)):
            first_c,second_c,third_c=(x, y * h), (x+1, y * h), ((x+0.5, (y+1) * h))
            first_sc, second_sc,third_sc=(x+1, y * h), (x+1.5, (y+1) * h), (x+0.5, (y+1) * h)
        return first_c, second_c,third_c, first_sc, second_sc,third_sc                                            
            #return [(x, y * h), (x+1, y * h), (x+0.5, (y+1) * h)] ,[(x+1, y * h), (x+1.5, (y+1) * h), (x+0.5, (y+1) * h)]

##Generates the two triangles  coordinates
first_c, second_c,third_c, first_sc, second_sc,third_sc=generate_coordinates_for_unit_triangles(50,50)

#convert image into numpy array
image_read=Image.open(image_path)
image_to_numpy=np.asarray(image_read)
shape_of_array=image_to_numpy.shape

print(shape_of_array)
mask_image=[first_c, second_c,third_c, first_sc, second_sc,third_sc] 

I realized that this may not given my desired output.

The expected input and output is included below: [Expected input and output][1]

Any guidance on how to approach the problem would be appreciated. [1]: https://i.stack.imgur.com/vr7rV.jpg

pa1912
  • 17
  • 1
  • 7
  • 1
    You'll need to be more specific about the constraints. Do you always want 6 tiles? Must the base always be horizontal? Must they always be the same size? Always equilateral? Can you provide a standard template? – Mark Setchell Mar 10 '21 at 21:57
  • 1
    What are you going to DO with these pieces? You can't have a triangular bitmap, of course. Do you want to overlay them on a larger white rectangle as your example shows? There's no such thing as a "triangle bitblt", so you will be copying the pixels one by one. That's not hard, but it is tedious. – Tim Roberts Mar 10 '21 at 22:59
  • @MarkSetchell Equilateral triangle pieces. I do not need a fixed number of tile – pa1912 Mar 10 '21 at 23:49
  • @TimRoberts After slicing the triangles i need to join them together to create positive and negative samples for data training. – pa1912 Mar 10 '21 at 23:50
  • "Join" in what way? As I said, you can't have a triangular bitmap. Images in memory are square. You've come up with the vertices for the triangles -- good start. Now you need to copy them somewhere else. Where? What does that look like? – Tim Roberts Mar 11 '21 at 00:21
  • @TimRoberts Juxtaposing two pieces together.It's like joining pieces for jigsaw puzzles. Two pieces that match will be classed as positive and the pieces that do not match will be classed as negative. – pa1912 Mar 11 '21 at 11:09
  • It seems to me that you do not have a detailed step-by-step flowchart of what you want to do. You can't code it unless you can describe each step in a way that can be broken down into other steps. – Tim Roberts Mar 11 '21 at 18:53
  • @TimRoberts I do not as i am lost overall I assumed that I could generate triangle coordinates for the image and then pass that through a mask which would go through the pixels of the image and slice them into triangles. However, I realized this may not be possible as my generate_coordinates_for_unit_triangles function does not work. It only returns the very last coordinate. – pa1912 Mar 11 '21 at 21:43
  • That SPECIFIC problem, I can solve. Change the "return" at the end of `generate_coordinates_for_unit_triangles` to `yield`, and indent it one step so it's in the `y` loop. Now you can do `for coords in generate_coordinates_for_unit_triangles(50,50):` / `print(coords)` and see the whole list. – Tim Roberts Mar 11 '21 at 22:00
  • Those are very small triangles. – Tim Roberts Mar 11 '21 at 22:00
  • I do not know if this will help you, but see Skimage piecewise affine transform based upon triangulation at https://scikit-image.org/docs/dev/api/skimage.transform.html#skimage.transform.PiecewiseAffineTransform – fmw42 Mar 12 '21 at 04:52

1 Answers1

0

I'm posting this as an answer because it's long, but it's not literally an answer. I'm hoping this will lead you to the next step in your design process.

Here are the design decisions you face, It's clear from your code that you can generate a list of triangle coordinates. Good, what next? You probably know the bounding box of your triangles (largest w and h) advance, so you can certainly create a set of images that contain your triangles, masked off with a black background or alpha=0 background. You could just copy the bounding rectangle to an image, then create a mask using the triangle as a path, and set the alpha to 0 outside of the mask. opencv should be able to do that.

But after you have those, what then? You talked about matching the edges. That's complicated. I suppose you could extract a vector of pixels from the three edges of each triangle, and then do some kind of approximate comparison.

If you do find matches that allow you to stitch together a composite, it is possible (assuming you have alpha=0 in the backgrounds) to blit all of these triangles back into some larger image, kind of like quilting. openvc can do block copy with alpha blending.

So, in the end, I think your problem is achievable, but it's going to be a lot of work, and probably more than we can offer here.

Tim Roberts
  • 48,973
  • 4
  • 21
  • 30