I would like to know the area inside the spaces between one line and another and then cut them into separate images.
def grid(width, height, wq, hq):
img = Image.new('RGB', (width, height), color='white')
pic = ImageDraw.Draw(img)
for i in range(0, width, wq):
for j in range(0, height, hq):
pic.line([(i, j), (i + wq, j + hq)], fill="red", width=10)
img.show()
grid(600,600,300,300)
Find the areas, and save the two triangles and the two trapezoids in separate images
This isn't going to be easy with PIL, though you probably could do it using ImageDraw.floodfill()
to fill in the trapezoids one at a time and then find their locations using Numpy
.
I would suggest you use OpenCV and its findContours()
. I would also suggest you ditch full-colour processing if you just want to find an area of one thing and not another thing which reduces processing time and memory pressure. Specifically also, if using OpenCV you need to look for white objects on a black background, so I adapted your code to look like this:
#!/usr/bin/env python3
from PIL import Image, ImageDraw
import numpy as np
import cv2
def grid(width, height, wq, hq):
img = Image.new('L', (width, height), color='white')
pic = ImageDraw.Draw(img)
for i in range(0, width, wq):
for j in range(0, height, hq):
pic.line([(i, j), (i + wq, j + hq)], fill="black", width=10)
return img
im = grid(600,600,300,200)
im.save('result.png')
# Make into Numpy array for OpenCV
na = np.array(im)
# Find the contours
contours, _ = cv2.findContours(na,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
for i, c in enumerate(contours):
# Calculate area
area = cv2.contourArea(c)
print(f'Contour: {i}, area: {area} pixels')
# Make new, empty output image
out = np.zeros((na.shape[0], na.shape[1]), np.uint8)
# Draw in the contour
cv2.drawContours(out,[c],0,255,thickness=cv2.FILLED)
cv2.imwrite(f'contour-{i}.png', out)
Here are the output images, one per contour, all horizontally merged onto a grey background so you can determine the extent of each:
Here are the output areas:
Contour: 0, area: 27936.5 pixels
Contour: 1, area: 84432.0 pixels
Contour: 2, area: 112819.5 pixels
Contour: 3, area: 28130.0 pixels
Contour: 4, area: 84626.5 pixels
Contour: 5, area: 0.0 pixels
There are many more features you can test for such as arc length, centroids, moments, circularity, minimum area but I'll leave that up to you.
You can also use the images generated above as masks and bitwise_and()
them with your image to extract just the white areas.
Remember that you can do your processing in greyscale but still use the resulting masks and areas and apply them to your original full-colour input image.
If you have some objection to using OpenCV, note that you could use scikit-image
and its label and regionprops.