-2

I'm new to Python. I'm using Glob to Batch Process multiple image files. When I run my code, it processes and saves all image files as it should, but only one image file is affected by my code all other image files are untouched by my code. I need all images to be affected by my code. When I run my code on the two Checker Board image files, only one image file is affected the other image file is untouched by my code as shown in the images.

I tried researching more to find a solution, but I couldn't find one here is my code.

Thanks in advance,

import numpy as np
import cv2
import os
import glob
from skimage import img_as_ubyte

image_list = []

path = "opencv/imgs/*.*"

for file in glob.glob(path):
    print(file)
    img = cv2.imread(file)
    a = cv2.imread(file)
    image_list.append(img)

    print(a)
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    edges = cv2.Canny(gray,50,200,apertureSize=3)
    img_blur = cv2.GaussianBlur(gray, (3,5), 2)
    edges = cv2.Canny(image=img_blur, threshold1=25, threshold2=50) # Canny Edge Detection

# Apply HoughLinesP method to 
# to directly obtain line end points
lines_list =[]
lines = cv2.HoughLinesP(
            edges, # Input edge image
            1, # Distance resolution in pixels
            np.pi/2, # Angle resolution in radians
            threshold=225, # Min number of votes for valid line
            minLineLength=60, # Min allowed length of line
            maxLineGap=400) # Max allowed gap between line for joining them
           
 
# Iterate over points
for points in lines:
      # Extracted points nested in the list
    x0,y1,x0,y2=points[0]
    # Draw the lines joing the points
    # On the original image
    cv2.line(img,(x0,y1),(x0,y2),(0,255,0),4)
    # Maintain a simples lookup list for points
    lines_list.append([(x0,y1),(x0,y2)])

image_list = np.array(image_list)
    
# Save the result image
img_number = 1
for image in range(image_list.shape[0]):
        input_img = image_list[image,:,:]
        lines_image = img_as_ubyte(input_img)
        cv2.imwrite(path+str(img_number)+".jpg", lines_image)
        img_number +=1 
5
  • In the first for-loop you only assign image objects to some variables without further storing or processing the images. The variables are overwritten with each iteration and only the images of the last iteration are kept for further processing after the loop. You would have to include large parts of the further processing in the first for-loop. Commented Jun 22 at 19:25
  • I can only recommend the Python tutorial for Python in general and sites like leetcode.com for practicing by solving programming tasks. Practicing is generally the most important way to learn to program. Commented Jun 22 at 22:52
  • Maybe first use print() (and print(type(...)), print(len(...)), etc.) to see which part of code is executed and what you really have in variables. It is called "print debugging" and it helps to see what code is really doing.
    – furas
    Commented Jun 22 at 23:41
  • you have wrong indentations - you have to do all calculation inside for-loop. You calculate edge inside for-loop (so you do it for all images) but later you calculate HoughLinesP outside for-loop so you do it only for one file. And rest of code has the same problem. If you would use print() to see which line of code is executed and what you have in variables then you should see problem. Maybe create function which gets filename and it make all calculations for one file - and it save this file - and later run this function in for file in glob.glob(path):
    – furas
    Commented Jun 22 at 23:44
  • frankly, I don't understand your last for-loop. You should write directly img - and you should do it inside for file in glob.glob(path):
    – furas
    Commented Jun 23 at 0:00

1 Answer 1

0

All your problem it because you have wrong indentations. You run edge for every image (because it is still inside for-loop) but you run HoughLinesP outside for-loop so it is executed for only one image.

And I don't understand why later you use other another for-loop.
You should save current image in first loop and this loop will go to the beginning to process next image

Something like this:

import glob
import cv2

folder = "opencv/imgs" 
path = f"{folder}/*.*"

for index, file in enumerate(glob.glob(path), 1):
    print(index, 'file:', file)

    # read only one file

    img = cv2.imread(file)
    print(img)

    # process only one file
    
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    edges = cv2.Canny(gray, 50, 200, apertureSize=3)
    img_blur = cv2.GaussianBlur(gray, (3, 5), 2)
    edges = cv2.Canny(image=img_blur, threshold1=25, threshold2=50) # Canny Edge Detection

    # Apply HoughLinesP method to 
    # to directly obtain line end points
    lines = cv2.HoughLinesP(
                edges,            # Input edge image
                1,                # Distance resolution in pixels
                np.pi/2,          # Angle resolution in radians
                threshold=225,    # Min number of votes for valid line
                minLineLength=60, # Min allowed length of line
                maxLineGap=400)   # Max allowed gap between line for joining them
           
    # Iterate over points
    lines_list = []
    for points in lines:
        # Extracted points nested in the list
        x0, y1, x0, y2 = points[0]
        
        # Draw the lines joing the points
        # On the original image
        cv2.line(img, (x0, y1), (x0, y2), (0, 255, 0), 4)
        
        # Maintain a simples lookup list for points  ???
        lines_list.append([(x0,y1),(x0,y2)])

    # write only one file

    cv2.imwrite(f"{folder}/{index}.jpg", img)

    # end of current loop - go back to the beginning to work with next image

To make it more visible you could create function which gets one filename and it makes all calculation for one image, and it saves one image. And run this function in for-loop.

import glob
import cv2

def process_one_file(index, file, target_folder):
    print(index, 'file:', file)

    # read only one file

    img = cv2.imread(file)
    print(img)

    # process only one file
    
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    edges = cv2.Canny(gray, 50, 200, apertureSize=3)
    img_blur = cv2.GaussianBlur(gray, (3, 5), 2)
    edges = cv2.Canny(image=img_blur, threshold1=25, threshold2=50) # Canny Edge Detection

    # Apply HoughLinesP method to 
    # to directly obtain line end points
    lines = cv2.HoughLinesP(
                edges,            # Input edge image
                1,                # Distance resolution in pixels
                np.pi/2,          # Angle resolution in radians
                threshold=225,    # Min number of votes for valid line
                minLineLength=60, # Min allowed length of line
                maxLineGap=400)   # Max allowed gap between line for joining them
           
    # Iterate over points
    lines_list = []
    for points in lines:
        # Extracted points nested in the list
        x0, y1, x0, y2 = points[0]
        
        # Draw the lines joing the points
        # On the original image
        cv2.line(img, (x0, y1), (x0, y2), (0, 255, 0), 4)
        
        # Maintain a simples lookup list for points  ???
        lines_list.append([(x0,y1),(x0,y2)])

    # write only one file

    cv2.imwrite(f"{target_folder}/{index}.jpg", img)

    # exit function
    
# --- main ---    

folder = "opencv/imgs" 
path = f"{folder}/*.*"

for index, file in enumerate(glob.glob(path), 1):
    process_one_file(index, file, folder)
    # end of current loop - go back to the beginning to work with next image
1
  • Thanks so much Furas you're right all my problems were my indentations. You really helped me a great deal thanks for your time.
    – Mark
    Commented Jun 24 at 0:24

Not the answer you're looking for? Browse other questions tagged or ask your own question.