Image processing with Python (Part 2)

Write the code to binarize all the TIFF files in the specified folder.

Recursively search for folders

It's really easy to dig a folder. There was a method called os.walk (). There is no need to make a function like finddir () to recursively call it.

import os
for root, dirs,files in os.walk("."):
    for f in files:
        print(os.path.join(root, f))

That's why I was able to display all the files in the current folder.

With os.walk (), you can get all files and all subdirectories under the directory specified as a list of root, dir, files. In this case, files is a list of files, so extract them one by one while storing them in a variable called f. You can join it as a file path from root by doing os.path.join ().

Perform image binarization

Executes binarization processing for all image files in the specified folder.

import cv2
import os
import numpy as np
from matplotlib import pyplot as plt

for root,dirs,files in os.walk("img"):
    for f in files:
        if os.path.splitext(f)[1] == ".tiff":
            img = cv2.imread(os.path.join(root, f), 0)
            blur = cv2.GaussianBlur(img,(5,5),0)
            ret,imgb = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

For the time being, this allows you to binarize all files with the extension ".tiff" under the img folder. First, by specifying 0 as the second argument with cv2.imread (), the image file is read as a gray image, and then Gaussian blur is applied with cv2.GaussianBlur (). After that, binarize with cv2.THRESH_BINARY + cv2.THRESH_OTSU.

Get the signal

Since the return value of cv2.threshold () is a binarized image this time, it is a two-dimensional array, and either 0 or 255 is stored for each pixel. For example, a 3x3 black and white checkered pattern looks like this.

([255,0,255],
 [0,255,0]
 [255,0,255])

The binarized image is a black image on a white background. A black pixel is a pixel whose element is 0. So, if we were to scan all these pixels and count the number of pixels that had a signal, we would get the vertical and horizontal sizes of the image and from (x, y) = (0,0) to (x, y). The process will be repeated until = (max (x), max (y)).

The coordinates of the image file are somehow written as (x, y) on the horizontal axis X vertical axis Y, but the pixel information of the image acquired as a two-dimensional array of numpy is in the order of "row" and "column". Since it is described, when extracting the signal of the pixel at the position of (x, y) = (300, 200) confirmed by ImageJ etc. from the numpy array, it is necessary to specify it as array [200, 300]. .. If you think about it, you can understand it, but I often make a mistake.

The following is a display that counts the number of black pixels from a black binarized image on a white background.

cnt=0
for x in range(0, imgb.shape[0]):
    for y in range(0, imgb.shape[1]):
        if imgb[x,y] == 0:
            cnt += 1
print(cnt)

In reality, this is a numpy array, so if you just want to scan all the elements, it's a little easier.

cnt =0
for val in imgb.flat:
    if val == 0:
        cnt += 1
print(cnt)

I got an error when I wrote cnt ++ for cnt increment like other languages.

The image under a certain folder is binarized and the number of pixels with a signal is counted.

The code so far can be summarized as follows. For only the ".tiff" file under the img folder, the image is binarized and the number of pixels with a signal of 0 is counted.

import numpy as np
import cv2
from matplotlib import pyplot as plt
import os

for root,dirs,files in os.walk("img"):
    for f in files:
        if os.path.splitext(f)[1] == ".tiff":
            img = cv2.imread(os.path.join(root, f), 0)
            blur = cv2.GaussianBlur(img,(5,5),0)
            ret,imgb = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
            cnt = 0
            for val in imgb.flat:
                if val == 0:
                    cnt += 1
            print( f + ":\t" + str(cnt) )

Create a function

Since the above processing is img folder fixed or .tiff extension fixed, a series of processing is summarized as a function so that this can be specified freely. The first argument is the target folder and the second argument is the extension of the target file.

import numpy as np
import cv2
from matplotlib import pyplot as plt
import os

def convert_and_count( dir, ext ):
    for root,dirs,files in os.walk(dir):
        for f in files:
            if os.path.splitext(f)[1] == ext:
                img = cv2.imread(os.path.join(root, f), 0)
                blur = cv2.GaussianBlur(img,(5,5),0)
                ret,imgb = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
                cnt = 0
                for val in imgb.flat:
                    if val == 0:
                        cnt+=1
                msg = f + ":\t" + str(cnt)
                print( msg )

if __name__ == "__main__":
    convert_and_count( "img", ".tiff" )

If you do so far, the nest will be deeper and the outlook will be a little worse. Python expresses blocks by the number of indents, so if you try to do something a little complicated, the nest gets deeper and deeper. You may have to write the code in appropriate blocks so that it doesn't go too deep. Occasionally, when editing across several editors, tabs and spaces are mixed, and the level of nest that looks and the nest that the python interpreter understands are inconsistent, resulting in an error.

It doesn't make much sense, but what percentage of the total "black area" in the binarized image? If you want to ask that, add a line to calculate the sole in the defined convert_and_count () variable.

def convert_and_count( dir, ext ):
    for root,dirs,files in os.walk(dir):
        for f in files:
            if os.path.splitext(f)[1] == ext:
                img = cv2.imread(os.path.join(root, f), 0)
                blur = cv2.GaussianBlur(img,(5,5),0)
                ret,imgb = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
                cnt = 0
                for range in imgb.flat:
                    if val == 0:
                        cnt += 1
                ratio = cnt / imgb.size
                msg = f  + ":\t" + str(ratio)
                print( msg )

What if you want to display the calculated ratio up to 3 decimal places? An image like printf (“% .3f”, ratio); in C language. When I thought about it, it looked like the following.

msg = "%s:\t%.3f" % (f, ratio)

As mentioned above, by using Python, it was possible to easily perform binarization of images.

Recommended Posts

Image processing with Python (Part 2)
Image processing with Python (Part 1)
Image processing with Python (Part 3)
Image processing with Python
[Python] Image processing with scikit-image
python image processing
Image processing with Python 100 knocks # 3 Binarization
Image processing with Python 100 knocks # 2 Grayscale
Basics of binarized image processing with Python
Image processing with Python 100 knock # 10 median filter
Image processing with MyHDL
Image processing with Python 100 knocks # 8 Max pooling
First Python image processing
100 Language Processing Knock with Python (Chapter 2, Part 2)
Image processing with Python & OpenCV [Tone Curve]
Image processing with Python 100 knock # 12 motion filter
100 Language Processing Knock with Python (Chapter 2, Part 1)
Drawing with Matrix-Reinventor of Python Image Processing-
Easy image processing in Python with Pillow
Image processing with Python 100 knocks # 7 Average pooling
Light image processing with Python x OpenCV
Image processing with Python 100 knocks # 9 Gaussian filter
Image Processing with PIL
Image processing from scratch with python (5) Fourier transform
Image processing from scratch with python (4) Contour extraction
Image Processing with Python Environment Setup for Windows
100 Language Processing with Python Knock 2015
Studying Python with freeCodeCamp part1
Bordering images with python Part 1
Image processing with PIL (Pillow)
"Apple processing" with OpenCV3 + Python3
Scraping with Selenium + Python Part 1
Image editing with python OpenCV
Acoustic signal processing with Python (2)
Acoustic signal processing with Python
Sorting image files with Python (2)
Sorting image files with Python (3)
Studying Python with freeCodeCamp part2
Tweet with image in Python
Sorting image files with Python
Solving Sudoku with Python (Part 2)
Image processing by python (Pillow)
Image Processing Collection in Python
Scraping with Selenium + Python Part 2
Notes on HDR and RAW image processing with Python
Cut out an image with python
Real-time image processing basics with opencv
Playing handwritten numbers with python Part 1
[Python] Using OpenCV with Python (Image Filtering)
[Python] Easy parallel processing with Joblib
[Automation with python! ] Part 1: Setting file
100 Language Processing Knock with Python (Chapter 1)
[Python] Using OpenCV with Python (Image transformation)
100 Language Processing Knock with Python (Chapter 3)
Personal notes for python image processing
Let's do image scraping with Python
Find image similarity with Python + OpenCV
Automate simple tasks with Python Part0
[Automation with python! ] Part 2: File operation
Send image with python, save with php
Excel aggregation with Python pandas Part 1