Error specifying the file path in Python - python

I am new to python and do not know it very well.
I want modified the online code to convert my image data to lmdb form.
I given the root of my src and dst like below:
paths_src = 'F:\caffe-windows\caffe-windows\data\sift-flow\test\'
path_dst = 'F:\caffe-windows\caffe-windows\data\sift-flow\testlmdb'
but after i run the code I got a error. it seem that my path is wrong? can anyone help? I also attach the code.
import os
import numpy as np
from scipy import io
import lmdb
import caffe
from PIL import Image
NUM_IDX_DIGITS = 10
IDX_FMT = '{:0>%d' % NUM_IDX_DIGITS + 'd}'
print '1111'
paths_src = 'F:\\caffe-windows\\caffe-windows\\data\\sift-flow\\test\\'
path_dst = 'F:\\caffe-windows\\caffe-windows\\data\\sift-flow\\testlmdb'
print '2222'
def img_to_lmdb(paths_src,path_dst):
in_db = lmdb.open(path_dst, map_size=int(1e9))
with in_db.begin(write=True) as in_txn:
for in_idx, in_ in enumerate(paths_src):
print 'img:::'+str(in_)
# load image:
# - as np.uint8 {0, ..., 255}
# - in BGR (switch from RGB)
# - in Channel x Height x Width order (switch from H x W x C)
im = np.array(Image.open(in_)) # or load whatever ndarray you need
im = im[:,:,::-1]
im = im.transpose((2,0,1))
im_dat = caffe.io.array_to_datum(im)
in_txn.put('{:0>10d}'.format(in_idx), im_dat.SerializeToString())
in_db.close()
img_to_lmdb(paths_src,path_dst)
print '3333'

I am not familiar with this library but your problem starts in this line-
for in_idx, in_ in enumerate(paths_src):
because paths_src is a string, which is iterable, the builtin function enumerate simply goes through each one of the characters in that string, so the first item would be the letter 'F' and not the entire path.
What you should do is define paths_src as a list. so instead of:
paths_src = 'F:\\caffe-windows\\caffe-windows\\data\\sift-flow\\test\\'
you should do:
paths_src = ['F:\\caffe-windows\\caffe-windows\\data\\sift-flow\\test\\']
Hope I was helpful.

Related

OpenCV (Python) VideoCapture.read() on missing frames

New to python, new to OpenCV, which I'm gonna use for my master-thesis, and already got some problems using the VideoCapture object of OpenCV.
Situation:
I got 2 folders containing corresponding images (taken with RGB and infrared cameras). I want to display them sibe by side in a Window using a while-loop. The problem arises, when there are some images missing from one of the image-sequences (Due to problems while recording or whatever, I don't really know but that should be of no importance). My idea was to use the bool-returnvalue of the .read() function to check wheather there is a frame to be read and if not, replace the image by a black one. This is what I did:
Code:
import cv2
import numpy as np
pathRGB = "Bilder/RGB"
pathIR = "Bilder/IR"
# the paths to the folders containing the images
capRGB = cv2.VideoCapture(pathRGB + "/frame_%06d.jpg")
capIR = cv2.VideoCapture(pathIR + "/frame_%06d.jpg")
# setting up the VideoCapture-elements with the according format
shapeRGB = capRGB.read()[1].shape
shapeIR = capIR.read()[1].shape
# get the shape of the first image in each folder to later create the black
# dummy-image
dtypeRGB = capRGB.read()[1].dtype
dtypeIR = capIR.read()[1].dtype
# get the type of the first image in each folder to later create the black
# dummy-image
if (capRGB.isOpened() is False):
print("Error opening RGB images")
if (capIR.isOpened() is False):
print("Error opening IR images")
cv2.namedWindow("frames", cv2.WINDOW_NORMAL)
while capRGB.isOpened() and capIR.isOpened() is True:
retRGB, imgRGB = capRGB.read()
retIR, imgIR = capIR.read()
# read both images
if retRGB is True and retIR is False:
imgIR = np.zeros(shapeIR, dtype=dtypeIR)
# if there is no IR image, crate a dummy one
if retIR is True and retRGB is False:
imgRGB = np.zeros(shapeRGB, dtype=dtypeRGB)
# if there is no RGB image, crate a dummy one
if retRGB is False and retIR is False:
break
imgCombined = np.hstack((imgRGB, imgIR))
# put both images together
cv2.imshow("frames", imgCombined)
k = cv2.waitKey(1)
if k == ord("q"):
break
capRGB.release()
capIR.release()
cv2.destroyAllWindows()
Problem:
From my understanding, the problem arises as capIR.read() attempts to read a missing image (in my case the 527th) and instead of just returning false/None it attempts to read the same image over and over again. Up to the missing frame, everything works fine, the right "IR" image even turns black but then the videoplayback begins to slow down and while i still can close the window by pressing 'q', spyder IDE freezes and if I wait "too long" i even have to shut it down. Console gives out "[image2 # 000002a7af8f0480] Could not open file : Bilder/IR/frame_000527.jpg" over and over again, so much that i can't scroll to the top.
I guess what I'm asking is: Is there any way to make the .read() function just attempt 1 read and after it fails continue with the next frame?
Best regards and thank you very much in advance!
Simulated for testing with different files and directory names.
Will retrieve the largest frame number from both directories and afterwards iterate over all frame numbers for reading the files from both directories.
import os
import cv2
import re
import glob
image_dir1 = 'test1'
image_dir2 = 'test2'
# retrieve all frames in both directories
frames_cap1 = glob.glob(os.path.join(image_dir1, "frame_*.jpg"))
frames_cap2 = glob.glob(os.path.join(image_dir2, "frame_*.jpg"))
# sort inscending
frames_cap1.sort()
frames_cap2.sort()
# retrieve last frame No for both directories
last_frame_cap1 = frames_cap1[-1]
last_frame_cap2 = frames_cap2[-1]
# extract integer counter as a group
# modify regex to match file name if required
match_cap1 = re.search('frame_(\d+).jpg', last_frame_cap1)
match_cap2 = re.search('frame_(\d+).jpg', last_frame_cap2)
last_frame_no_cap1 = int(match_cap1.group(1))
last_frame_no_cap2 = int(match_cap2.group(1))
# retrieve max frame No
max_frame_no = max(last_frame_no_cap1, last_frame_no_cap2)
for i in range(max_frame_no + 1):
# adapt formatting of frame number to digit count in file name
# here: 6 digits with leading zeros
image_path_cap1 = os.path.join(image_dir1, f"frame_{i:06d}.jpg")
image_path_cap2 = os.path.join(image_dir2, f"frame_{i:06d}.jpg")
if not os.path.isfile(image_path_cap1):
print(f"handle missing file: '{image_path_cap1}'")
# ...
else:
img1 = cv2.imread(image_path_cap1)
# …
if not os.path.isfile(image_path_cap2):
print(f"handle missing file: '{image_path_cap2}'")
# ...
else:
img2 = cv2.imread(image_path_cap2)
# …
# …
Assuming that the images in directory1 have the same names as directory2 images, but we know that some image may not be present in both directories...
import glob,os,cv2
path1 = "folder1/"
path2 = "folder2/"
#change directory to path1
os.chdir(path1)
l1 = glob.glob("*.jpg") #get a list of images names
os.chdir("../") #go one directory up
blackimg = cv2.imread("blackimg.jpg")
for fname in l1:
#check if image1 exists , then read it . otherwise im1 = blackimg
if os.path.isfile(path1+fname):
im1=cv2.imread(path1+fname)
else:
im1=blackimg
#check if image2 exists , then read it . otherwise im2 = blackimg
if os.path.isfile(path2+fname):
im2=cv2.imread(path2+fname)
else:
im2=blackimg
imgCombined = np.hstack((im1, im2))
cv2.imshow("Combined", imgCombined)
print("press any key to continue, q to exit")
k = cv2.waitKey(0)
if k == ord("q"):break
cv2.destroyAllWindows()

How to use pyautogui for images

I was wondering if it was possible to do pyautogui.locateOnScreen() for a full folder this is what i mean a folder with 20 different images and finding them on the screen. Is it possible to do with pyautogui? or else how would you do it?
This is my code so far:
from pyautogui import locateAllOnScreen as find
import os
import numpy as np
def try_to_find(x):
x = os.path.isfile(x)
if x == None:
Warning('No images were enterd')
else:
folder = x
value = find(folder)
if value is not None:
print(f"{x} was found!")
else:
if value is None:
print(f"{x} was not found!")
return(list(value))
myfolder = ("ImageQuery")
found = 0
with os.scandir(myfolder) as entries:
for entry in entries:
if entry.is_file():
found+=1
print(f'Items {found}: {entry.name}')
try_to_find(entry.name)
i get this error if i run this code TypeError: expected an image filename, OpenCV numpy array, or PIL image
Try this out:
import os
import pyautogui as py
image_list = []
# Get list of all files in current directory
directory = os.listdir()
# Find files that end with .png or .jpg and add to image_list
for file in directory:
if file.endswith('.png') or file.endswith('.jpg'):
image_list.append(file)
# Loop through list to find all the images
for image in image_list:
print(image)
print(py.locateOnScreen(image))
This question is similar to another one, I posted the same answer in both places.

How to read the mask of an image using opencv in python

I am working on this challenge called Carvana Segmentation in kaggle. The dataset consists of 5088 images, for each image there is a mask. For eg, the below is a single image (.jpg file) and its corresponding mask (.gif file).
I was able to read .jpg files using cv2, but not the .gif files. The syntax i used to read .gif file is
>>> image = cv2.imread('filename.gif',cv2.IMREAD_GRAYSCALE)
When I try to print the image, returns None
>>> print(image) -> None
Can someone suggest any other method, please
imageio allows to read gifs like this:
import imageio
img = imageio.imread('filename.gif')
Following this repo:
https://github.com/asharma327/Read_Gif_OpenCV_Python/blob/master/gif_to_pic.py
you can do the following to read the image
import cv2
import os
def convert_gif_to_frames(gif):
# Initialize the frame number and create empty frame list
frame_num = 0
frame_list = []
# Loop until there are frames left
while True:
try:
# Try to read a frame. Okay is a BOOL if there are frames or not
okay, frame = gif.read()
# Append to empty frame list
frame_list.append(frame)
# Break if there are no other frames to read
if not okay:
break
# Increment value of the frame number by 1
frame_num += 1
except KeyboardInterrupt: # press ^C to quit
break
return frame_list
def output_frames_as_pics(frame_list):
# Reduce the list of frames by half to make the list more managable
frame_list_reduce = frame_list[0::2]
# Get the path of the current working directory
path = os.getcwd()
# Set then name of your folder
'''Replace this name with what you want your folder name to be'''
folder_name = 'Picturebook_Pics_Kiss'
# If the folder does not exist, then make it
if not os.path.exists(path + '/' + folder_name):
os.makedirs(path + '/' + folder_name)
for frames_idx in range(len(frame_list_reduce)):
cv2.imwrite(os.path.join(path + '/' + folder_name, str(frames_idx+1) + '.png'), frame_list_reduce[frames_idx])
return
gif = cv2.VideoCapture('/home/ahmedramzy/Documents/gif/giphy.gif')
# here you can get the frames and work on it
xx = convert_gif_to_frames(gif_kiss)
# here if you want to write it on hard disk using imwrite
output_frames_as_pics(xx)
You can't use imread(), there's no codec for that builtin (still a license problem)[https://answers.opencv.org/question/185929/how-to-read-gif-in-python/]
Since you are interested in python, you may use PIL library as mentioned here.
from PIL import Image
im = Image.open("animation.gif")
# To iterate through the entire gif
try:
while 1:
im.seek(im.tell()+1)
# do something to im
except EOFError:
pass # end of sequence

Pyautogui use size() to get two integers

so I am trying to create a bot in python, and for that cause I would need the size of the screen as two integers (x coordinate and y coordinate). I use pyautogui for that case, but the function size() only returns a string:
Size(width=2560, height=1440)
How would i go about "extracting" these values into integer variables?
edit: I managed to fix my problem, it's some spagetthi code, but I can clean it up later, just in case someone has the same problem:
import pyautogui
screen_size = str(pyautogui.size())
screen_size_x, screen_size_y = screen_size.split(",")
screen_size_x= screen_size_x.replace("Size(width=","")
screen_size_y = screen_size_y.replace("height=","")
screen_size_y = screen_size_y.replace(")","")
screen_size_y = screen_size_y.replace(" ","")
screen_size_x = int(screen_size_x)
screen_size_y = int(screen_size_y)
print(screen_size_x)
print(screen_size_y)
from inspect import getsource
print(getsource(pyautogui.size))
output:
def size():
"""Returns the width and height of the screen as a two-integer tuple.
Returns:
(width, height) tuple of the screen size, in pixels.
"""
return Size(*platformModule._size())
nicer code:
import pyautogui
x,y = pyautogui.size()
x,y=int(str(x)),int(str(y))
print(x)
print(y)
I've found multiple examples online of using pyautogui.size(). In all those examples, that method returns a two-item tuple containing width and height. So it seems that your code could be as simple as:
screen_size_x, screen_size_y = pyautogui.size()
print(screen_size_x)
print(screen_size_y)
This is shown in the first example in the pyautogui docs: https://github.com/asweigart/pyautogui/blob/master/README.md
If you did need to parse the string you mention, here's a cleaner way to do that:
import re
str = "Size(width=2560, height=1440)"
m = re.search(r"width=(\d+).*height=(\d+)", str)
screen_size_x, screen_size_y = int(m.group(1)), int(m.group(2))
print(screen_size_x)
print(screen_size_y)

How to extract and save images from tensorboard event summary?

Given a tensorflow event file, how can I extract images corresponding to a specific tag, and then save them to disk in a common format e.g. .png?
You could extract the images like so. The output format may depend on how the image is encoded in the summary, so the resulting write to disk may need to use another format besides .png
import os
import scipy.misc
import tensorflow as tf
def save_images_from_event(fn, tag, output_dir='./'):
assert(os.path.isdir(output_dir))
image_str = tf.placeholder(tf.string)
im_tf = tf.image.decode_image(image_str)
sess = tf.InteractiveSession()
with sess.as_default():
count = 0
for e in tf.train.summary_iterator(fn):
for v in e.summary.value:
if v.tag == tag:
im = im_tf.eval({image_str: v.image.encoded_image_string})
output_fn = os.path.realpath('{}/image_{:05d}.png'.format(output_dir, count))
print("Saving '{}'".format(output_fn))
scipy.misc.imsave(output_fn, im)
count += 1
And then an example invocation may look like:
save_images_from_event('path/to/event/file', 'tag0')
Note that this assumes the event file is fully written -- in the case that it's not, some error handling is probably necessary.
For those who can also do without code, there is an elegant way in the Tensorboard UI.
In the upper left corner, select the checkbox Show data download links
In the lower left corner, select the download icon which lets you download a svg file.
In the lower right corner, select data download links for the raw data, handy for those who want to do more sophisticated data analysis or data visualization
If you are using TensorFlow 2, this works nicely
from collections import defaultdict, namedtuple
from typing import List
import tensorflow as tf
TensorBoardImage = namedtuple("TensorBoardImage", ["topic", "image", "cnt"])
def extract_images_from_event(event_filename: str, image_tags: List[str]):
topic_counter = defaultdict(lambda: 0)
serialized_examples = tf.data.TFRecordDataset(event_filename)
for serialized_example in serialized_examples:
event = event_pb2.Event.FromString(serialized_example.numpy())
for v in event.summary.value:
if v.tag in image_tags:
if v.HasField('tensor'): # event for images using tensor field
s = v.tensor.string_val[2] # first elements are W and H
tf_img = tf.image.decode_image(s) # [H, W, C]
np_img = tf_img.numpy()
topic_counter[v.tag] += 1
cnt = topic_counter[v.tag]
tbi = TensorBoardImage(topic=v.tag, image=np_img, cnt=cnt)
yield tbi
Although, 'v' has an image field, it is empty.
I used
tf.summary.image("topic", img)
to add the images to the event file.

Categories

Resources