0

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

The image

Here's the file in the folder

Now, I would like to use the threshold on the entire set at once. How can I do so ?

14
  • 1
    You will need to get the list of images and loop over them thresholding them one-by-one inside the loop. Search Google for examples, such as quora.com/… Commented Mar 24, 2020 at 20:55
  • Unfortunately, I couldn't do such a thing I always get errors Commented Mar 24, 2020 at 20:57
  • How can I loop over them ? (I've tried and it didn't work) Commented Mar 24, 2020 at 20:58
  • You could not do what? Search Google or apply the example I referenced to read multiply images? If the latter, please show your code attempt. Perhaps you have a simple error. Commented Mar 24, 2020 at 20:58
  • Here is another link, stackoverflow.com/questions/49537604/… and answers.opencv.org/question/74459/… and medium.com/@basit.javed.awan/… Commented Mar 24, 2020 at 21:05

3 Answers 3

0

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]

Sign up to request clarification or add additional context in comments.

Comments

0

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)


7 Comments

Doesn,t work : I get an error on the last line :TypeError: Expected Ptr<cv::UMat> for argument 'img'
from glob import glob import cv2 img_mask = r'C:\Users\Bsi\Desktop\PFE\Mine*.png' out_dir = r'C:\Users\Bsi\Desktop\PFE\Mine\NEWDIR' img_names = glob(img_mask) for fn in img_names: print('processing %s...' % fn,) im_gray = cv2.imread(fn, 0) thresh=127 im_gray = cv2.threshold(im_gray, thresh, 255, cv2.THRESH_BINARY) cv2.imwrite(r'out_dir\fn', im_gray)
Just a minute. The formatting of the output_dir/fn is in error. I am correcting and testing.
Okay ! I'm still waiting for your comment
Sorry, it took me so long. I had to debug, because I had accidentally left in a back slash () in Window syntax and I need a forward slash on my Mac. I also had forgot that your input names include the input directory path and I needed to remove the path to get just the names of the images and write them to the out_dir. See the changed code in my answer. Change your filenames and paths appropriately for your system and OS.
|
0

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.

1 Comment

import glob import cv2 import numpy as np images= [cv2.imread(file) for file in glob.glob("C:/Users/st/Image/*.jpg")]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.