Nice to meet you, this is Qiita's first post.
I usually work mainly on Ruby, but recently I started studying python as a hobby and found that it was surprisingly easy to process images, so I wrote about simple image processing. I wrote this article and its sequel to my blog (http://www.uosansatox.biz/).
I'm still studying python, so if you don't write this for python, it's slow, or the code is dirty, please let me know in the comments.
Also, the code below uses the python library, numpy, pillow. In the author's environment, Anaconda3 is used on windows10, so it was not necessary to install it separately, but please install it if necessary when executing it.
Image processing is achieved by simply changing the color of each pixel from end to end of the image. Therefore, first read the image file and convert it into a three-dimensional array whose size is image height x image width x 3 for easy operation. By doing this, for example, the color of the 100th pixel from the left and the 200th pixel from the top of the image will be It will be available as img_pixels [100] [200]. The acquired value will be an array `` `[r, g, b] ``` with 3 elements. First of all, I will explain the minimum pillow (PIL) usage and common processing used in image processing.
Import the required libraries at the beginning of the line. The images used for clarity are placed in the same folder as the py file.
edit_img.py
from PIL import Image
import numpy as np
#Loading the original image
img = Image.open('original.jpg')
#Get the width and height of the original image
width, height = img.size
#Create an Image object that is the same size as the original image
img2 = Image.new('RGB', (width, height))
Converts the read original image into an array.
img_pixels = []
for y in range(height):
for x in range(width):
# getpixel((x,y))Xth from the left,Get the color of the yth pixel from the top and img_Add to pixels
img_pixels.append(img.getpixel((x,y)))
#Convert it to a numpy array for easy calculation later
img_pixels = np.array(img_pixels)
By the way, you can also write in one line as follows.
python
img_pixels = np.array([[img.getpixel((i,j)) for j in range(height)] for i in range(width)])
As I wrote above, get the color of each pixel as follows
img_pixels[100][200]
# => array([255,255,255])
To set the color to the 100th pixel from the left and the 200th pixel from the top of the processed image object img2 as follows Use the putpixel method. In the example below, it is set to blue. To set it to red, set the last three arguments to 255,0,0.
img2.putpixel((100, 200), (0, 0, 255))
Use the show method to display the edited image instance.
img2.show()
Use the save method to save.
img2.save('edited_img.jpg')
Let's actually process the image using the above method. The following original images are used for image processing. I used the image of Mr. Pakutaso (https://www.pakutaso.com/), a free image site.
Implements blurring that makes the entire image look a little hazy. The drawback is that the image becomes smaller by the size of the filter. Create an image that looks like it is blurred by writing the average color with the surrounding colors to the image after processing. Actually, I wanted to take the average with the colors on the top, bottom, left, and right when viewed from the starting point, but for the sake of simplicity, I take the average with the colors on the lower right.
bokashi.py
from PIL import Image
import numpy as np
img = Image.open('original.jpg')
width, height = img.size
filter_size = 20
img2 = Image.new('RGB', (width - filter_size, height - filter_size))
img_pixels = np.array([[img.getpixel((x,y)) for x in range(width)] for y in range(height)])
filter_size = 20
for y in range(height - filter_size):
for x in range(width - filter_size):
#position(x,y)Cut out an image with a small vertical and horizontal filter size from the original image starting from
partial_img = img_pixels[y:y + filter_size, x:x + filter_size]
#Align the values of each pixel in a small image
color_array = partial_img.reshape(filter_size ** 2, 3)
#Each R,G,B Find the average of each and the position of the processed image(x,y)Set to the pixel value of
mean_r, mean_g, mean_b = color_array.mean(axis = 0)
img2.putpixel((x,y), (int(mean_r), int(mean_g), int(mean_b)))
img2.show()
img2.save('bokashi.jpg')
The following is the output image.
Generates an image that looks like a mosaic over the entire image. Creates a (single color) image with the darkest color and the same size as the partial image among the partial images for the vertical and horizontal filter sizes. Create a mosaic image by fitting the created single color image into the processed image one after another.
mozaiku.py
from PIL import Image
import numpy as np
img = Image.open('original.jpg')
width, height = img.size
filter_size = 10
img2 = Image.new('RGB', (width, height))
img_pixels = np.array([[img.getpixel((x,y)) for x in range(width)] for y in range(height)])
#
def draw_partial_img(img2, start_x, start_y, partial_size_x, partial_size_y, pixel_color):
for y in range(start_y, start_y + partial_size_y):
for x in range(start_x, start_x + partial_size_x):
img2.putpixel((x, y), pixel_color)
for y in range(0, height, filter_size):
for x in range(0, width, filter_size):
#Cut out a part of the image in the same way as blurring
partial_img = img_pixels[y:y + filter_size, x:x + filter_size]
#Convert to an array of colors
color_array = partial_img.reshape(partial_img.shape[0] * partial_img.shape[1], 3)
#R for each pixel+ g +Get the number of the thing b takes the maximum value
#The darkest color number in the image cut out
max_index = np.argmax(color_array.sum(axis=1))
max_r, max_g, max_b = color_array[max_index]
# (x,y)Single color with vertical and horizontal filter size starting from(The above colors)Set the image of to img2
draw_partial_img(img2, x, y, partial_img.shape[1], partial_img.shape[0], (max_r, max_g, max_b))
img2.show()
img2.save('mozaiku.jpg')
The following is the output result. It's unpleasant because it has a quadruple loop, but an image of this size was displayed in a few seconds.
Produces a negative-like color-inverted image.
hanten.py
from PIL import Image
import numpy as np
img = Image.open('original.jpg')
width, height = img.size
img2 = Image.new('RGB', (width, height))
img_pixels = np.array([[img.getpixel((x,y)) for x in range(width)] for y in range(height)])
#Invert colors
reverse_color_pixels = 255 - img_pixels
for y in range(height):
for x in range(width):
#Create an image with inverted colors
r,g,b = reverse_color_pixels[y][x]
img2.putpixel((x,y), (r,g,b))
img2.show()
img2.save('hanten.jpg')
Below is the generated image. It's scary, probably because the original image is beautiful, but it's beautiful even if it's inverted.
Actually, a method to invert the color to pillow is prepared, but this time I implemented image processing with the help of numpy for python practice.
It was an unreasonable sentence, but thank you for reading to the end.
There is something I want to do a little more, so I may add it again.
I wrote a sequel to this article on the linked site below. If you want to do more things, please visit us. Color reduction processing by k-means clustering Generation of coloring book Create a miniature image Unsharp Masking Blanarization and 3 thresholds Speeding up the repeating part Expansion and contraction
Recommended Posts