'Thresholding multiple images in Python using OpenCv
I would like to binarize a whole folder of images and save them. I've already found a code that binarizes a single image and store it in the same folder:
import cv2
im_gray = cv2.imread('blurredimg1.png', cv2.IMREAD_GRAYSCALE)
(thresh, im_bw) = cv2.threshold(im_gray, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
thresh = 127
im_bw = cv2.threshold(im_gray, thresh, 255, cv2.THRESH_BINARY)[1]
cv2.imwrite('bw_image.png', im_bw)
Here's the output
Now, I would like to use the threshold on the entire set at once. How can I do so ?
Solution 1:[1]
Here it is :
from glob import glob
import cv2
img_mask = r'C:\Users\Bsi\Desktop\PFE\Mine\*.png'
img_names = glob(img_mask)
for fn in img_names:
print('processing %s...' % fn,)
im_gray = cv2.imread(fn, 0)
(thresh, im_bw) = cv2.threshold(im_gray, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
thresh = 127
im_bw = cv2.threshold(im_gray, thresh, 255, cv2.THRESH_BINARY)[1]
Solution 2:[2]
The following is tested and works in Unix path syntax on my Mac in Python/OpenCV. And I am not a Windows user. So you will need to modify the paths appropriately for your OS and change my "/" to "\" where they are specifically shown in the paths
You need to define the path to where you want to put the output directory to hold the created images. I used in_dir and out_dir. the out_dir directory needs to exist already.
So something like the following. Where I get the OTSU threshold outside the loop and save the threshold value from your blurred image. Then I loop over all the images in the input directory via your img_mask. I threshold each image using the threshold that was saved and then write the file to disk inside the loop.
from glob import glob
import os
import cv2
# read your one blurred image and convert to gray
im_gray = cv2.imread('test/lena.png', 0)
# threshold it with OTSU thresholding and get the threshold value
thresh, im_bw = cv2.threshold(im_gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
print(thresh)
# define the paths to your input images and to where you want to put the output images
in_dir = 'test'
out_dir = 'test2'
# read the input image file names with paths into a list
infiles = in_dir + '/*.png'
img_names = glob(infiles)
print(img_names)
# loop over each input image in a for loop
for fn in img_names:
print('processing %s...' % fn)
# read an input image as gray
im_gray = cv2.imread(fn, 0)
# threshold it with your saved threshold
im_bw = cv2.threshold(im_gray, thresh, 255, cv2.THRESH_BINARY)[1]
# write the result to disk in the previously created output directory
name = os.path.basename(fn)
outfile = out_dir + '/' + name
cv2.imwrite(outfile, im_bw)
Solution 3:[3]
You can use two for loops to do so. I was facing the same issue.
for i, val in enumerate(images_gray):
ret,thresh1 = cv2.threshold(images_gray[i],110,255,cv2.THRESH_BINARY)
ret,thresh2 = cv2.threshold(images_gray[i],70,255,cv2.THRESH_BINARY_INV)
ret,thresh3 = cv2.threshold(images_gray[i],127,255,cv2.THRESH_TRUNC)
ret,thresh4 = cv2.threshold(images_gray[i],77,255,cv2.THRESH_TOZERO)
ret,thresh5 = cv2.threshold(images_gray[i],127,255,cv2.THRESH_TOZERO_INV)
titles = ['Original Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
images = [images_gray[i], thresh1, thresh2, thresh3, thresh4, thresh5]
for k in range(6):
plt.rcParams["figure.figsize"] = (20,10)
plt.subplot(45,6,k+1),plt.imshow(images_gray[i],'gray', vmin=0,vmax=255)
plt.title(titles[k])
k+=1
plt.xticks([]),plt.yticks([])
plt.show()
i+=1
I made use of 45 images. And wanted to show a 6 threshold comparison.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Sabrina |
| Solution 2 | |
| Solution 3 | Dharman |
