Write the code to binarize all the TIFF files in the specified folder.
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 ().
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.
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 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) )
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