0

I have this code

But I'm having difficulty in labeling the patches of each image in a certain pattern for instance i have a image with name 000_train now its patches should be named as 000_train_00................000_train_01 and so on or for 671_train its patch should be 671_train_00..............671_train_01 and so on

so I have 671 images, So each image patches should have name that uniquely identifies its original image but as well as automatically store the each image cropped images in separate folders respectively with name 0,1..........

import numpy as np
import cv2
import glob
from os import listdir
from os.path import isfile, join
from PIL import Image
import os

#look_up_table={"Ab":"0","An":"1","Di":"2","He":"3","Is":"4","Ky":"5","Kyr":"6","Me":"7","Pi":"8","Vi":"9"}

path = r"C:/Users/55/.spyder-py3/IAM/Train/"
save_path = "C:/Users/55/.spyder-py3/IAM/train_patches/"

# path = r"C:/Users/55/.spyder-py3/IAM/Test/"
# save_path = "C:/Users/55/.spyder-py3/IAM/test_patches/"

image_files = [f for f in os.listdir(path) if f.endswith('.png')]


def load_labels(path):
  labels=[]
  fileList = glob.glob(os.path.join(path,"*.png"))
  for fname in fileList:
      fileName=os.path.basename(fname)
      curLabel=fileName
      labels.append(curLabel)
      return np.asarray(labels)

def load_data(path):
     fileList=glob.glob(path) 
     x=np.array([np.array(Image.open(fname)).flatten() for fname in fileList])
     x=x/255 #img size grey scale
     return x

def imcrop(img, bbox): 
    x1,y1,x2,y2 = bbox
    if x1 < 0 or y1 < 0 or x2 > img.shape[1] or y2 > img.shape[0]:
        img, x1, x2, y1, y2 = pad_img_to_fit_bbox(img, x1, x2, y1, y2)
    return img[y1:y2, x1:x2, :]

def pad_img_to_fit_bbox(img, x1, x2, y1, y2):
    img = np.pad(img, ((np.abs(np.minimum(0, y1)), np.maximum(y2 - img.shape[0], 0)),
               (np.abs(np.minimum(0, x1)), np.maximum(x2 - img.shape[1], 0)), (0,0)), mode="constant")
    y1 += np.abs(np.minimum(0, y1))
    y2 += np.abs(np.minimum(0, y1))
    x1 += np.abs(np.minimum(0, x1))
    x2 += np.abs(np.minimum(0, x1))
    return img, x1, x2, y1, y2

for file in image_files:
    w=0
    sample_image = cv2.imread(path+str(file))
    # get dimensions of image
    dimensions = sample_image.shape

    # height, width, number of channels in image
    height = sample_image.shape[0]
    width = sample_image.shape[1]
    channels = sample_image.shape[2]

    print('Image Dimension    : ',dimensions)
    print('Image Height       : ',height)
    print('Image Width        : ',width)
    print('Number of Channels : ',channels)

    window_width=500
    window_height=500

    writer = file.split("fileName")[0]
    #writer = load_labels(path)

    for i in range(0,height,window_height):
        for j in range(0,width,window_width): 
#            for temp in writer:
           # if crop_image==window_width && window_height
            crop_image = sample_image[i:i+window_height,j:j+window_width]
            cv2.imwrite(save_path+str(writer)+"_"+str(w)+".png",crop_image)
            w=w+1
            #else
            #

  • Please don't vandalize your own question by removing the source code and/or (relevant) information. That's against the "content licensing" of Stack Overflow, – HansHirse Dec 12 '19 at 05:41

1 Answers1

0

With the following changes, your code does what you want to achieve:

[...]

path = 'images/'
save_path = "train_patches/"
image_files = [f for f in os.listdir(path) if f.endswith('.jpg')]
#w=0                                                # <-- Moved w=0 from here...

[...]

for file in image_files:
    w=0                                             # <-- ... to here

    [...]

    writer = file.split('.')[0]                     # <-- Split at . to get rid of the file extension
    #writer = load_labels(path)                     # <-- Why?

    for i in range(0,height,window_height):
        for j in range(0,width,window_width): 
            #for image_files in writer:             # <-- Why?
            crop_image = sample_image[i:i+window_height,j:j+window_width]
            cv2.imwrite(save_path+str(writer)+"_"+str(w)+".png",crop_image)
            w=w+1

So, since you're iterating all files in

for file in image_files:

you must reset w=0 inside this loop, such that your patch counter starts at 0 for every image. The rest is getting the correct filename without the file extension. Cave at: There are definitely better ways to do that, but the above change was the minimal change to your existing code.

Hope that helps!


EDIT: Here's a minimal example incorporating the changed/additional subject:

import cv2
import os

path = 'images/'
save_path = 'train_patches/'

if not os.path.isdir(save_path):
    os.mkdir(save_path)

image_files = [f for f in os.listdir(path) if f.endswith('.jpg')]

for file in image_files:
    w = 0

    sample_image = cv2.imread(path + str(file))

    height = sample_image.shape[0]
    width = sample_image.shape[1]

    window_width = 500
    window_height = 500

    writer = file.split('.')[0]

    if not os.path.isdir(save_path + '/' + writer + '/'):
        os.mkdir(save_path + '/' + writer + '/')

    for i in range(0, height, window_height):
        for j in range(0, width, window_width):
            crop_image = sample_image[i:i+window_height, j:j+window_width]
            cv2.imwrite(save_path + '/' + writer + '/' + str(w) + '.png', crop_image)
            w = w + 1

for root, dirs, files in os.walk(save_path):
    path = root.split(os.sep)
    print((len(path) - 1) * '---', os.path.basename(root))
    for file in files:
        print(len(path) * '---', file)

Output:

 another_jpg_image
--- 0.png
--- 1.png
--- 10.png
--- 11.png
--- 2.png
--- 3.png
--- 4.png
--- 5.png
--- 6.png
--- 7.png
--- 8.png
--- 9.png
 a_jpg_image
--- 0.png
--- 1.png
 the_last_jpg_image
--- 0.png
--- 1.png

(The last part was taken from this Q&A.)

OpenCV's imwrite can't generate folders on it's own, that has to be done explicitly, cf. this Q&A.

HansHirse
  • 18,010
  • 10
  • 38
  • 67
  • yes but i need to store crop images of each image in separate folder with labels 0, 1 and so on respectively. so precisely to say , folders should be generated via code only```cv2.imwrite(........................+save_path+str(writer)+"_"+str(w)+".png",crop_image)``` i think this need to be edited but i dont know how –  Dec 12 '19 at 05:33
  • @S.Ohanzee So, something like `save_path+str(writer)+"/"+str(w)+".png"` instead of `save_path+str(writer)+"_"+str(w)+".png"`!? – HansHirse Dec 12 '19 at 05:38
  • ```cv2.imwrite(save_path+str(writer)+"/"+str(w)+".png",crop_image)``` will this also let the cropped images have the same name as its original name with _labels(0,1.......) –  Dec 12 '19 at 06:02
  • @S.Ohanzee I added another attempt. Even if that's still not what you want, I will now stop further supporting here. You changed the subject and source code of your question after getting a valid answer to your original problem. Also, I don't want to support [help vampirism](https://meta.stackoverflow.com/questions/258206/what-is-a-help-vampire). Please have a thorough look at the Stack Overflow guidelines. – HansHirse Dec 12 '19 at 06:36
  • Oh i didnt know how to add another question as i have question limit –  Dec 12 '19 at 06:43