Join extracted/splitted patches to reconstruct an image - python

i used this code below to extract patches from a image.
extract code:
import os
import glob
from PIL import Image
Image.MAX_IMAGE_PIXELS = None # to avoid image size warning
imgdir = "/path/to/image/folder"
filelist = [f for f in glob.glob(imgdir + "**/*.png", recursive=True)]
savedir = "/path/to/image/folder/output"
start_pos = start_x, start_y = (0, 0)
cropped_image_size = w, h = (256, 256)
for file in filelist:
img = Image.open(file)
width, height = img.size
frame_num = 1
for col_i in range(0, width, w):
for row_i in range(0, height, h):
crop = img.crop((col_i, row_i, col_i + w, row_i + h))
name = os.path.basename(file)
name = os.path.splitext(name)[0]
save_to= os.path.join(savedir, name+"_{:03}.png")
crop.save(save_to.format(frame_num))
frame_num += 1
Now i want to reconstruct this imagem from all those patches extracted before, i've tried 2 diffenret codes
so my DB is 120x256x256x3 extracted patches, theres 120 patches to fit in 3840x2048 shape..:
patches = []
for directory_path in glob.glob('D:\join_exemplo'):
for img_path in glob.glob(os.path.join(directory_path, "*.png")):
img = cv2.imread(img_path,1)
patches.append(img)
input_patches = np.array(patches)
first i've tried sklearn.feature_extraction.image importing reconstruct_from_patches_2d, but got a black image:
reconstruct = reconstruct_from_patches_2d(input_patches, input_image)
reconstruct = reconstruct.astype(np.uint8)
Image.fromarray(reconstruct, 'RGB').save(r'D:\join_exemplo\re\re3.png')
also tried, this below but got a grayscale tone pattern image
input_image = (3840,2048,3)
reconstructed_arr = np.zeros(shape=(3840,2048,3))
#%%
>>> step = 256
>>> for x in range(img.shape[0]):
for y in range(img.shape[1]):
x_pos, y_pos = x * step, y * step
reconstructed_arr[x_pos:x_pos + 512, y_pos:y_pos + 512] = img[x, y, 0, ...]
>>> (input_image == reconstructed_arr).all()
True
cv2.imwrite(r'D:\join_exemplo\re\re.png',reconstructed_arr)
Can someone see whats wrong? sorry about my bad english

Related

How can I check shape for generated images?

I have images with different width and height
I want to reshape generated images so that width and height are same
So I used following function that check and change shape of images
But there was an error that shape was None type when "size = h if h >= w else w"
How can I check and change shape of Images?
def preprocessing(image, label):
# add padding
h, w = image.shape[0], image.shape[1]
# h, w, _ = tf.shape(image)
size = h if h >= w else w
dst = tf.image.pad_to_bounding_box(image, int((size-h)/2), int((size-w)/2), size, size)
dst = tf.image.resize(dst, size=(2048, 2048))
# image augmentation
dst = tf.image.random_crop(dst, size=(1843, 1843, 3))
dst = tf.image.resize(dst, size=(2048, 2048))
dst = tf.image.random_flip_left_right(dst)
dst = tf.cast(dst, tf.float32)
dst = (dst / 127.5) - 1
return dst, label
dt = dataset_train.map(preprocessing, num_parallel_calls=tf.data.experimental.AUTOTUNE)
dt = dt.batch(32).prefetch(3)
dv = dv.batch(32).prefetch(3)
enter image description here

add_argument(..., type=argparse.FileType('r')) but then arg is None

I want to restore the big size images of the Tiny ImageNet dataset from the ImageNet dataset. I found the code in this repository but I faced this error that 'NoneType' object is not iterable. What is the problem and How can I fix this problem?
import argparse, os, os.path, glob, random, sys, json
from collections import defaultdict
from lxml import objectify
from matplotlib.pyplot import imread
from imageio import imwrite
import cv2
#from scipy.misc import imresize
from matplotlib.patches import Rectangle
import matplotlib.pyplot as plt
import numpy as np
train_anns_path = '/home/user/tiny_imagenet/LOC_train_solution.csv'
train_image_dir = '/data/imagenet/Data/CLS-LOC/train'
val_anns_path = '/home/user/tiny_imagenet/LOC_val_solution.csv'
val_image_dir = '/data/imagenet/Data/CLS-LOC/val'
def get_synset_stats():
with open('words.txt') as f:
wnid_to_words = dict(line.strip().split('\t') for line in f)
wnids = os.listdir(train_anns_path)
wnid_to_stats = {wnid: {} for wnid in wnids}
for i, wnid in enumerate(wnids):
synset_dir = os.path.join(train_anns_path, wnid)
bbox_files = os.listdir(synset_dir)
bbox_files = [os.path.join(synset_dir, x) for x in bbox_files]
glob_str = '%s_*.JPEG' % wnid
img_files = glob.glob(os.path.join(train_image_dir, glob_str))
wnid_to_stats[wnid]['bbox_files'] = bbox_files
wnid_to_stats[wnid]['img_files'] = img_files
wnid_to_stats[wnid]['num_imgs_train'] = len(img_files)
wnid_to_stats[wnid]['num_loc_train'] = len(bbox_files)
wnid_to_stats[wnid]['words'] = wnid_to_words[wnid]
#print >> sys.stderr, i
#print '%d\t%s\t%s\t%d\t%d' % (
# i, wnid, wnid_to_words[wnid], len(bbox_files), len(img_files))
def parse_xml_file(filename):
with open(filename, 'r') as f:
xml = f.read()
ann = objectify.fromstring(xml)
img_filename = '%s.JPEG' % ann.filename
bbox = ann.object.bndbox
bbox = [bbox.xmin, bbox.ymin, bbox.xmax, bbox.ymax]
bbox = [int(x) for x in bbox]
name = str(ann.object.name)
return img_filename, bbox, name
def resize_image(img, size, bbox=None, crop=True, show=False):
"""
Resize an image and its bounding box to a square.
img - A numpy array with pixel data for the image to resize.
size - Integer giving the height and width of the resized image.
bbox - Optionally, a list [xmin, ymin, xmax, ymax] giving the coordinates
of a bounding box in the original image.
crop - If true, center crop the original image before resizing; this avoids
distortion in images with nonunit aspect ratio, but may also crop out
part of the object.
show - If true, show the original and resized image and bounding box.
Returns:
If bbox was passed: (img_resized, bbox_resized)
otherwise: img_resized
"""
def draw_rect(coords):
width = coords[2] - coords[0]
height = coords[3] - coords[1]
rect = Rectangle((coords[0], coords[1]), width, height,
fill=False, linewidth=2.0, ec='green')
plt.gca().add_patch(rect)
img_resized = img
if bbox is not None:
bbox_resized = [x for x in bbox]
if crop:
h, w = img.shape[0], img.shape[1]
if h > w:
h0 = (h - w) / 2
if bbox is not None:
bbox_resized[1] -= h0
bbox_resized[3] -= h0
img_resized = img[h0:h0+w, :]
elif w > h:
w0 = (w - h) / 2
if bbox is not None:
bbox_resized[0] -= w0
bbox_resized[2] -= w0
img_resized = img[:, w0:w0+h]
if bbox is not None:
h_ratio = float(size) / img_resized.shape[0]
w_ratio = float(size) / img_resized.shape[1]
ratios = [w_ratio, h_ratio, w_ratio, h_ratio]
bbox_resized = [int(1 + r * (x - 1)) for x, r in zip(bbox_resized, ratios)]
bbox_resized = np.clip(bbox_resized, 0, size - 1)
img_resized = cv2.resize(img_resized, (size, size))
if show:
plt.subplot(1, 2, 1)
plt.imshow(img)
if bbox is not None:
draw_rect(bbox)
plt.subplot(1, 2, 2)
plt.imshow(img_resized)
if bbox is not None:
draw_rect(bbox_resized)
plt.show()
if bbox is None:
return img_resized
else:
return img_resized, bbox_resized
def write_data_in_synset_folders(part_data, part, out_dir, image_size):
part_dir = os.path.join(out_dir, part)
os.mkdir(part_dir)
num_wnids = len(part_data)
for i, (wnid, wnid_data) in enumerate(part_data.iteritems()):
#print 'Writing images for synset %d / %d of %s' % (i + 1, num_wnids, part)
wnid_dir = os.path.join(part_dir, wnid)
os.mkdir(wnid_dir)
image_dir = os.path.join(wnid_dir, 'images')
os.mkdir(image_dir)
boxes_filename = os.path.join(wnid_dir, '%s_boxes.txt' % wnid)
boxes_file = open(boxes_filename, 'w')
for i, (img_filename, bbox) in enumerate(wnid_data):
out_img_filename = '%s_%d.JPEG' % (wnid, i)
full_out_img_filename = os.path.join(image_dir, out_img_filename)
img = imread(img_filename)
img_resized, bbox_resized = resize_image(img, image_size, bbox)
imwrite(full_out_img_filename, img_resized)
boxes_file.write('%s\t%d\t%d\t%d\t%d\n' % (out_img_filename,
bbox_resized[0], bbox_resized[1], bbox_resized[2], bbox_resized[3]))
boxes_file.close()
def write_data_in_one_folder(part_data, part, out_dir, image_size):
part_dir = os.path.join(out_dir, part)
os.mkdir(part_dir)
# First flatten the part data so we can shuffle it
part_data_flat = []
for wnid, wnid_data in part_data.iteritems():
for (img_filename, bbox) in wnid_data:
part_data_flat.append((wnid, img_filename, bbox))
random.shuffle(part_data_flat)
image_dir = os.path.join(part_dir, 'images')
os.mkdir(image_dir)
annotations_filename = os.path.join(part_dir, '%s_annotations.txt' % part)
annotations_file = open(annotations_filename, 'w')
for i, (wnid, img_filename, bbox) in enumerate(part_data_flat):
if i % 100 == 0:
print ('Finished writing %d / %d %s images' % (i, len(part_data_flat), part))
out_img_filename = '%s_%s.JPEG' % (part, i)
full_out_img_filename = os.path.join(image_dir, out_img_filename)
img = imread(img_filename)
img_resized, bbox_resized = resize_image(img, image_size, bbox)
imwrite(full_out_img_filename, img_resized)
annotations_file.write('%s\t%s\t%d\t%d\t%d\t%d\n' % (
out_img_filename, wnid,
bbox_resized[0], bbox_resized[1], bbox_resized[2], bbox_resized[3]))
annotations_file.close()
def make_tiny_imagenet(wnids, num_train, num_val, out_dir, image_size=50, test=False):
if os.path.isdir(out_dir):
# print 'Output directory already exists'
return
# dataset['train']['n123'][0] = (filename, (xmin, ymin, xmax, xmax))
# gives one example of an image and bbox for synset n123 of the training subset
dataset = defaultdict(lambda: defaultdict(list))
for i, wnid in enumerate(wnids):
#print 'Choosing train and val images for synset %d / %d' % (i + 1, len(wnids))
# TinyImagenet train and val images come from ILSVRC-2012 train images
train_synset_dir = os.path.join(train_anns_path, wnid)
orig_train_bbox_files = os.listdir(train_synset_dir)
orig_train_bbox_files = {os.path.join(train_synset_dir, x) for x in orig_train_bbox_files}
train_bbox_files = random.sample(orig_train_bbox_files, num_train)
orig_train_bbox_files -= set(train_bbox_files)
val_bbox_files = random.sample(orig_train_bbox_files, num_val)
for bbox_file in train_bbox_files:
img_filename, bbox, _ = parse_xml_file(bbox_file)
img_filename = os.path.join(train_image_dir, img_filename)
dataset['train'][wnid].append((img_filename, bbox))
for bbox_file in val_bbox_files:
img_filename, bbox, _ = parse_xml_file(bbox_file)
img_filename = os.path.join(train_image_dir, img_filename)
dataset['val'][wnid].append((img_filename, bbox))
# All the validation XML files are all mixed up in one folder, so we need to
# iterate over all of them. Since this takes forever, guard it behind a flag.
# The name field of the validation XML files gives the synset of that image.
if test:
val_xml_files = os.listdir(val_anns_path)
for i, val_xml_file in enumerate(val_xml_files):
if i % 200 == 0:
print ('Processed %d / %d val xml files so far' % (i, len(val_xml_files)))
val_xml_file = os.path.join(val_anns_path, val_xml_file)
img_filename, bbox, wnid = parse_xml_file(val_xml_file)
if wnid in wnids:
img_filename = os.path.join(val_image_dir, img_filename)
dataset['test'][wnid].append((img_filename, bbox))
# Now that we have selected the images for the dataset, we need to actually
# create it on disk
os.mkdir(out_dir)
write_data_in_synset_folders(dataset['train'], 'train', out_dir, image_size)
write_data_in_one_folder(dataset['val'], 'val', out_dir, image_size)
write_data_in_one_folder(dataset['test'], 'test', out_dir, image_size)
parser = argparse.ArgumentParser()
parser.add_argument('--wnid_file', type=argparse.FileType('r'))
parser.add_argument('--num_train', type=int, default=100)
parser.add_argument('--num_val', type=int, default=100)
parser.add_argument('--image_size', type=int, default=64)
parser.add_argument('--out_dir')
args = parser.parse_args()
if __name__ == '__main__':
wnids = [line.strip() for line in args.wnid_file]
print (len(wnids))
# wnids = ['n02108089', 'n09428293', 'n02113799']
make_tiny_imagenet(wnids, args.num_train, args.num_val, args.out_dir,
image_size=args.image_size, test=True)
sys.exit(0)
train_synsets = os.listdir(train_anns_path)
get_synset_stats()
sys.exit(0)
The error is:
File "/home/user/tiny_imagenet/make_tiny_imagenet.py", line 238, in
wnids = [line.strip() for line in args.wnid_file]
TypeError: 'NoneType' object is not iterable
Based on your error:
wnids = [line.strip() for line in args.wnid_file] TypeError: 'NoneType' object is not iterable
I guess the problem is that args.wnid_file is None.
You need to verify that you pass the wnid_file correctly to your python script.

How to crop multiple images in a folder to a circular shape using PIL?

I have a folder of images and I want to crop them in a circular shape.
This is the original image:
The result that I want is this:
My code is:
import os
import glob
from PIL import Image, ImageDraw, ImageFilter
import numpy as np
def mask_circle_solid(pil_img, background_color, blur_radius, offset=0):
background = Image.new(pil_img.mode, pil_img.size, background_color)
offset = blur_radius * 2 + offset
mask = Image.new("L", pil_img.size, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((offset, offset, pil_img.size[0] - offset, pil_img.size[1] - offset), fill=255)
mask = mask.filter(ImageFilter.GaussianBlur(blur_radius))
return Image.composite(pil_img, background, mask)
def mask_circle_transparent(pil_img, blur_radius, offset=0):
offset = blur_radius * 2 + offset
mask = Image.new("L", pil_img.size, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((offset, offset, pil_img.size[0] - offset, pil_img.size[1] - offset), fill=255)
mask = mask.filter(ImageFilter.GaussianBlur(blur_radius))
result = pil_img.copy()
result.putalpha(mask)
return result
def crop_max_square(pil_img):
return crop_center(pil_img, min(pil_img.size), min(pil_img.size))
def crop_center(pil_img, crop_width, crop_height):
img_width, img_height = pil_img.size
return pil_img.crop(((img_width - crop_width) // 2,
(img_height - crop_height) // 2,
(img_width + crop_width) // 2,
(img_height + crop_height) // 2))
im = []
for f in glob.iglob("./*.jpg"):
im.append(np.asarray(Image.open(f)))
thumb_width = 150
im = np.array(im)
list_files = os.listdir(".")
list_files.sort()
list_files.remove("Test.py")
list_files.remove(".DS_Store")
for i in range(0,len(im)):
im_square[i] = crop_max_square(im[i]).resize((thumb_width, thumb_width), Image.LANCZOS)
im_thumb[i] = mask_circle_transparent(im_square[i], 4)
im_thumb[i].save(list_files[i])
I have used the functions from this article:
Generate square or circular thumbnail images with Python, Pillow
But I get this error:
line 30, in crop_max_square
return crop_center(pil_img, min(pil_img.size), min(pil_img.size))
TypeError: 'int' object is not iterable
I'm not sure if you really need to use numpy to load the files, but you can do what the "Sample code for batch processing" of the page you shared does:
import os
import glob
from PIL import Image, ImageDraw, ImageFilter
def mask_circle_solid(pil_img, background_color, blur_radius, offset=0):
background = Image.new(pil_img.mode, pil_img.size, background_color)
offset = blur_radius * 2 + offset
mask = Image.new("L", pil_img.size, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((offset, offset, pil_img.size[0] - offset, pil_img.size[1] - offset), fill=255)
mask = mask.filter(ImageFilter.GaussianBlur(blur_radius))
return Image.composite(pil_img, background, mask)
def mask_circle_transparent(pil_img, blur_radius, offset=0):
offset = blur_radius * 2 + offset
mask = Image.new("L", pil_img.size, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((offset, offset, pil_img.size[0] - offset, pil_img.size[1] - offset), fill=255)
mask = mask.filter(ImageFilter.GaussianBlur(blur_radius))
result = pil_img.copy()
result.putalpha(mask)
return result
def crop_max_square(pil_img):
return crop_center(pil_img, min(pil_img.size), min(pil_img.size))
def crop_center(pil_img, crop_width, crop_height):
img_width, img_height = pil_img.size
return pil_img.crop(((img_width - crop_width) // 2,
(img_height - crop_height) // 2,
(img_width + crop_width) // 2,
(img_height + crop_height) // 2))
im = []
jpgs_files_path = "./" # Replace the "./" path by the path where the .jpg images are.
files = glob.glob(os.path.join(jpgs_files_path, '*.jpg'))
thumb_width = 150
for f in files:
im = Image.open(f)
im_thumb = crop_max_square(im).resize((thumb_width, thumb_width), Image.LANCZOS)
im_thumb = mask_circle_transparent(im_thumb, 4)
ftitle, fext = os.path.splitext(os.path.basename(f))
im_thumb.save(os.path.join("./dstdir/", ftitle + '_thumbnail.png'), quality=95)
As JPG does not support transparency you need to discard the Alpha Channel or save as something that supports transparency like PNG.

Not getting correct results from pytesseract

I am trying to do OCR in python but not getting the correct output. Here is the code. I tried with original image, grayscale also but not getting any result
from PIL import Image
import pytesseract
def convert_to_monochrome(image):
pixels = image.load()
for i in range(image.size[0]): # for every pixel:
for j in range(image.size[1]):
r, g, b = pixels[i, j]
if r > 200 and g > 200 and b > 200:
pixels[i, j] = (255, 255, 255)
else:
pixels[i, j] = (0, 0, 0)
return image
def interpret_chips(image):
#image = image.resize((image.size[0] * 10, image.size[1] * 10), Image.ANTIALIAS)
#image = image.convert("LA")
#image.show()
_image = convert_to_monochrome(image)
_image.show()
_image.save("chips.jpg")
config = "--psm 7 -c tessedit_char_whitelist=0123456789KMT"
rank_string = pytesseract.image_to_string(_image, config=config) # expensive
return _image, rank_string
for i in range(1, 6):
print(i)
img = Image.open("temp/sample" + str(i) + ".jpg")
img, text = interpret_chips(img)
print(text)
img.save("temp/monochrome" + str(i) + ".jpg")
Thanks for your help
I am attaching some original images for which it is giving wrong results. Pre processed images are obtained after applying monochrome function defined please have a look. Text can be of type 4, 400, 4000, 459K, 29M etc. I am getting very awkward results.
Raw Image 1
Raw Image 2
Raw Image 3
Pre processed 1
Pre processed 2
Pre processed 3
The problem is that tesseract expects an image with dark text on a light background. The preprocessed image in your case is just the opposite. So you can just invert the preprocessed image.
Below code worked for me :
from PIL import Image
import pytesseract
def convert_to_monochrome(image):
pixels = image.load()
for i in range(image.size[0]): # for every pixel:
for j in range(image.size[1]):
r, g, b = pixels[i, j]
if r > 200 and g > 200 and b > 200:
pixels[i, j] = (0, 0, 0)
else:
pixels[i, j] = (255, 255, 255)
return image
def interpret_chips(image):
#image = image.resize((image.size[0] * 10, image.size[1] * 10), Image.ANTIALIAS)
#image = image.convert("LA")
#image.show()
_image = convert_to_monochrome(image)
_image.show()
_image.save("chips.jpg")
config = "--psm 6 -c tessedit_char_whitelist=0123456789KMT"
rank_string = pytesseract.image_to_string(_image, config=config) # expensive
return _image, rank_string
img = Image.open("orig.jpg")
img, text = interpret_chips(img)
print(text)
orig.jpg:
text is 23.000,

How to label images once importing them in python

I have a set of pictures, which are labelled dog, cat, truck, airplane and car in a folder. Once I import them in to python I want to assign them binary labels. The following code shows how I can extract pictures from the folder and do it for 1 class but how can I do it for multiple classes? For example 1 for 'dog', 2 for 'cat', 3 for 'truck', 4 for 'airplane' and 5 for 'car'.
Test_dir = "C:/Users/Instructor/Dropbox/Data Science/2.Temp_WORDFILES/test"
image_width = 32
image_height = 32
def read_images(directory, resize_to=(128, 128)):
"""This function extracts images from given
directory"""
files = glob.glob(directory + "/*.jpg")
images = []
labels = []
for f in tqdm.tqdm_notebook(files):
im = Image.open(f)
im = im.resize(resize_to)
im = np.array(im) / 255.0
im = im.astype("float32")
images.append(im)
label = 1 if "dog" in f.lower() else 0
labels.append(label)
return np.array(images), np.array(labels)
X, y = read_images(directory=Test_dir, resize_to=(IM_WIDTH, IM_HEIGHT))
Test_dir = "C:/Users/Instructor/Dropbox/Data Science/2.Temp_WORD FILES/test"
image_width = 32
image_height = 32
def read_images(directory, resize_to=(128, 128)):
"""This function extracts images from given
directory"""
files = glob.glob(directory + "/*.jpg")
images = []
labels = []
switch_values = {'dog':1,'cat':2, 'truck':3, 'airplane':4 ,'car':5}
for f in tqdm.tqdm_notebook(files):
im = Image.open(f)
im = im.resize(resize_to)
im = np.array(im) / 255.0
im = im.astype("float32")
images.append(im)
label = switch_values.get(f.lower())
labels.append(label)
return np.array(images), np.array(labels)
X, y = read_images(directory=Test_dir, resize_to=(IM_WIDTH, IM_HEIGHT))
Define a dictionary to map the animal name to label
animal_to_label = {'dog': 1,'cat': 2,'truck': 3,'airplane': 4,'car': 5 }
Test_dir = "C:/Users/Instructor/Dropbox/Data Science/2.Temp_WORDFILES/test"
image_width = 32
image_height = 32
def read_images(directory, resize_to=(128, 128)):
"""This function extracts images from given
directory"""
files = glob.glob(directory + "/*.jpg")
images = []
labels = []
switch_values = {'dog':1,'cat':2, 'truck':3, 'airplane':4 ,'car':5}
for f in tqdm.tqdm_notebook(files):
im = Image.open(f)
im = im.resize(resize_to)
im = np.array(im) / 255.0
im = im.astype("float32")
images.append(im)
name = f.split("/")[-1].split(".")[0]
label = animal_to_label[name.lower()]
labels.append(label)
return np.array(images), np.array(labels)
X, y = read_images(directory=Test_dir, resize_to=(IM_WIDTH, IM_HEIGHT))

Categories

Resources