Running a python.py file with datas - python

this code allows you to resize and view the file named "lena-gray.png" in the same folder.
from PIL import Image
jpgfile = Image.open("lena-gray.png")
high = input("Genişliğini giriniz : ")
wid = input("Yüksekliğini giriniz : ");
out = jpgfile.resize((int(high), int(wid)))
out.show()
But instead of entering these values step by step, I want to enter
$ python mywork.py lena-gray.png 50 100
So I want to run it without opening the file and see the result. Can this be done on Phyton? Can you help me?
----------------------------------------Edit----------------------------------
I updated my code like down.
import sys
from PIL import Image
firstarg = str(sys.argv[1])
secondarg = int(sys.argv[2])
thirdarg = int(sys.argv[3])
jpgfile = Image.open(firstarg)
yuks = secondarg
gen = thirdarg
out = jpgfile.resize((int(yuks), int(gen)))
out.show()
And my codes work!

You want to look into argparse.
It's the standard Python way to handle command line arguments.
EDIT: And if you want to check if the file is actually there or allow giving a list of files, look into glob.
EDIT2: This should do:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("filename", help="an image file", type=str)
parser.add_argument("width", help="display width", type=int)
parser.add_argument("height", help="display height", type=int)
clargs = parser.parse_args()
from PIL import Image
jpgfile = Image.open(clargs.filename)
out = jpgfile.resize(clargs.height, clargs.width)
out.show()
EDIT3: If you really want to do it according to the answer by #tendstoZero, this should be correct:
import sys
filename = sys.argv[1]
height = int(sys.argv[2])
width = int(sys.argv[3])
from PIL import Image
jpgfile = Image.open(filename)
out = jpgfile.resize(height, width)
out.show()
You shouldn't cast to int twice, and you shouldn't use meaningless intermediate variables.

import sys
firstarg=sys.argv[1]
secondarg=sys.argv[2]
thirdarg=sys.argv[3]
sys.argv[0] should be the script name .
You should be using something like this above snippet in your script.

Related

Is there a way to check if script is running from subprocess?

Let's say I have a python script which reads all the images in a folder and resizes them. The script works all by his own, it takes in two arguments - the input folder and an output folder.
To have a visual response of the progress I'm using a progressbar which is printed out to the console/terminal.
resize.py:
import argparse
import fnmatch
import os
import PIL
from PIL import Image
from progress.bar import Bar
parser = argparse.ArgumentParser(description='Photo resizer.')
parser.add_argument('input_folder', nargs='?', default='', help="Input folder")
parser.add_argument('export_folder', nargs='?', default='', help="Output folder")
args = parser.parse_args()
if args.input_folder:
input_folder = args.input_folder
if args.export_folder:
export_resized_folder = args.export_folder
NEW_SIZE = 2000
inputFiles = []
for root, dirnames, filenames in os.walk(input_folder):
for filename in fnmatch.filter(filenames, '*.jpg'):
inputFiles.append(os.path.join(root, filename))
bar = Bar("Processing photos", max=len(inputFiles), check_tty=False)
for photo in inputFiles:
filename = os.path.basename(photo)
im = Image.open(photo)
im_width, im_height = im.size
if im_width > im_height:
new_width = NEW_SIZE
new_height = int(NEW_SIZE * im_height / im_width)
else:
new_height = NEW_SIZE
new_width = int(NEW_SIZE * im_width / im_height)
new_size = (new_width, new_height)
im_resized = im.resize(new_size, resample=PIL.Image.Resampling.LANCZOS)
im_resized.save(os.path.join(export_resized_folder, filename), quality=70)
bar.next()
bar.finish()
Now I have an another script (main_gui.py) which does some batch processing and one of the jobs is to resize the images. This script provides a simple GUI. When it comes to resizing the images, I use subprocess Popen to execute the script and pass in the input and output folders as args.
So in main_gui.py I start the subprocess:
script_path = "resize.py"
process = subprocess.Popen(["python", script_path, INPUT_FOLDER, OUTPUT_FOLDER], universal_newlines=True, stdout=subprocess.PIPE)
Now I'd like to see the progress in the GUI also. I don't know if I'm doing it correctly (It is a high probability that not, this is just the first thing that came to my mind)...
So in resize.py along with the progressbar I print out information about my progress and then read it in the main_gui.py and based on that information I update a tkinter progressbar.
In resize.py:
bar = Bar("Processing photos", max=len(inputFiles), check_tty=False)
print("**TOTAL** " + str(len(inputFiles)))
...
progressCounter = 1
for photo in inputFiles:
...
bar.next()
print("**PROGRESS** " + str(progressCounter))
progressCounter += 1
...
I read these values in main_gui.py
process = subprocess.Popen(["python", script_path], universal_newlines=True, stdout=subprocess.PIPE)
while process.poll() is None:
data = process.stdout.readline().strip()
print(data)
if "**TOTAL** " in data:
total = int(data.replace("**TOTAL** ", ""))
progressbarWidget['maximum'] = total
if "**PROGRESS** " in data and self.GUI:
progressCounter = int(data.replace("**PROGRESS** ", ""))
progressbarWidget['value'] = progressCounter
progressbarWidget.update_idletasks()
And at this point I'd like in my resize.py check if it is run by itself or by the subprocess, so I don't have the unnecessary print statements.
I tried pass in an env value as Charles suggested in the comments, but couldn't get it done
Trying to detect your parent process is an unnecessary amount of magic for this use case. Making it explicit with an optional argument will let others writing their own GUIs (potentially in non-Python languages) get the machine-readable status output without needing to try to fool the detection.
parser = argparse.ArgumentParser(description='Photo resizer.')
parser.add_argument('--progress', choices=('none', 'human', 'machine-readable'), default='none',
help="Should a progress bar be written to stderr in a human-readable form, to stdout in a machine-readable form, or not at all?")
parser.add_argument('input_folder', nargs='?', default='', help="Input folder")
parser.add_argument('export_folder', nargs='?', default='', help="Output folder")
args = parser.parse_args()
...and then later...
if args.progress == 'machine-readable':
pass # TODO: Write your progress messages for the programmatic consumer to stdout here
elif args.progress == 'human':
pass # TODO: Write your progress bar for a human reader to stderr here
while on the GUI side, adding --progress=human to the argument list:
process = subprocess.Popen([sys.executable, script_path, '--progress=human'],
universal_newlines=True, stdout=subprocess.PIPE)

How to create a folder in python?

I am running a code in python where I get images from input file, and create another folder as output and a file csv. The code that I run is as below:
# import the necessary packages
from PIL import Image
import argparse
import random
import shutil
import glob2
import uuid
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--input", required = True,
help = "input directory of images")
ap.add_argument("-o", "--output", required = True,
help = "output directory")
ap.add_argument("-c", "--csv", required = True,
help = "path to CSV file for image counts")
args = vars(ap.parse_args())
# open the output file for writing
output = open(args["csv"], "w")
# loop over the input images
for imagePath in glob2.iglob(args["input"] + "/*/*.jpg"):
# generate a random filename for the image and copy it to
# the output location
filename = str(uuid.uuid4()) + ".jpg"
shutil.copy(imagePath, args["output"] + "/" + filename)
# there is a 1 in 500 chance that multiple copies of this
# image will be used
if random.randint(0, 500) == 0:
# initialize the number of times the image is being
# duplicated and write it to the output CSV file
numTimes = random.randint(1, 8)
output.write("%s,%d\n" % (filename, numTimes))
# loop over a random number of times for this image to
# be duplicated
for i in range(0, numTimes):
image = Image.open(imagePath)
# randomly resize the image, perserving aspect ratio
factor = random.uniform(0.95, 1.05)
width = int(image.size[0] * factor)
ratio = width / float(image.size[0])
height = int(image.size[1] * ratio)
image = image.resize((width, height), Image.ANTIALIAS)
# generate a random filename for the image and copy
# it to the output directory
adjFilename = str(uuid.uuid4()) + ".jpg"
shutil.copy(imagePath, args["output"] + "/" + adjFilename)
# close the output file
output.close()
After running the code I get only csv file, but I don't get output folder.
The way I run the code is:
python gather.py --input 101_ObjectCategories --output images --csv output.csv
Please can you help me how to solve the problem, because I need the output folder for next steps, running next functions.
I would recommend the following approach:
import os
from pathlib import Path
Path('path').mkdir(parents=True, exist_ok=True)
This works cross-platform and doesn't overwrite the directories if they already exist.
You should try the os module. It has a mkdir method that creates a directory based on the path you give it as a parameter.
import os
os.mkdir("path")
While most answers suggest using os.mkdir() I suggest you rather go for os.makedirs() which would recursively create all the missing folders in your path, which usually is more convinient.
import os
os.makedirs('foo/bar')
Docs: https://docs.python.org/3/library/os.html#os.makedirs

How do I convert multiple pictures, in a folder with ITK color map?

Every time I run my program in the terminal it prints out:
thumb0496.jpg is not converted
{} is not converted
Whatever I do it never works... I am new to Python and have installed it via Anaconda along with OpenCV, Pip and ITK. I have only been doing this for 4 days and am stuck. Python is my first language also. Why are my code not working?
In case this code looks similar it is. I had to try out with combining some elements. Unfortunately I cannot find the post again. The code was worse before but I (somehow) fixed it. It is just this (new) piece I can't fix on my own!
import cv2
import sys
import itk
import os,glob
from os import listdir,makedirs
from os.path import isfile,join
path = '/Users/admin/Desktop/ff'
dstpath = '/Users/admin/Desktop/test'
PixelType = itk.UC
Dimension = 2
ImageType = itk.Image[PixelType, Dimension]
RGBPixelType = itk.RGBPixel[PixelType]
RGBImageType = itk.Image[RGBPixelType, Dimension]
ColormapType = itk.CustomColormapFunction[PixelType, RGBPixelType]
colormap = ColormapType.New()
ColormapFilterType = itk.ScalarToRGBColormapImageFilter[ImageType,RGBImageType]
colormapFilter1 = ColormapFilterType.New()
colormapFilter1.SetInput(reader.GetOutput())
colormapFilter1.SetColormap(colormap)
WriterType = itk.ImageFileWriter[RGBImageType]
writer = WriterType.New()
writer.SetFileName(dstpath)
writer.SetInput(colormapFilter1.GetOutput())
try:
makedirs(dstpath)
except:
print ("Directory already exist, images will be written in same folder")
files = [f for f in listdir(path) if isfile(join(path,f))]
for image in files:
try:
reader = ReaderType(os.path.join(path,image))
map = ColormapFilterType(reader, PixelType, RGBImageType, ImageType)
dstPath = join(dstpath,image)
cv2.imwrite(dstPath,map)
except:
print ("{} is not converted".format(image))
for fil in glob.glob("*.jpg"):
try:
img = ReaderType(os.path.join(path,fil))
map_imag = ColormapType(img, PixelType, RGBImageType,ImageType)
cv2.imwrite(os.path.join(dstpath,fil),map_image)
except:
print('{} is not converted')
Why don't you start from a working example, and gradually change it to suit your needs? Examples can be found in the quick-start guide and this blog post.

Parsing arguments in python with any order

I am trying to parse command line arguments and I have never done it before. I have tried a few things. The code below is the last thing that I tried, but I received the error: "unrecognized arguments". I want to be able to put something like
copy-column-csv.py cname=Quiz source=source.csv target=target.csv out=out.csv
on the command line, but also have the ability to have it in any order. I am not sure how to go about this. Below is my code:
import argparse
import sys, re
import numpy as np
import smtplib
from random import randint
import csv
import math
import pandas as pd
parser = argparse.ArgumentParser()
parser.add_argument('-cname')
parser.add_argument('-source')
parser.add_argument('-target')
parser.add_argument('-out')
args = parser.parse_args()
#col = sys.argv[1]
#source = sys.argv[2]
#target = sys.argv[3]
#newtarg = sys.argv[4]
sourceFile = pd.read_csv(source)
targetFile = pd.read_csv(target)
del targetFile[cname]
targetFile[col] = pd.Series(sourceFile[col])
targetFile.to_csv(out, index = False)
Assuming well formed arguments, you could split sys.argv up into a dictionary:
args_dict = {}
for arg in sys.argv[1:]:
split = arg.split('=')
args_dict[split[0]] = split[1]
args_dict will look like this:
{'cname': 'Quiz',
'out': 'out.csv',
'source': 'source.csv',
'target': 'target.csv'}
And you can access the elements like so:
print args_dict['cname']
print args_dict['out']
print args_dict['source']
print args_dict['target']
Here is an example of how I'm doing it.
from optparse import OptionParser
from optparse import OptionGroup
parser = OptionParser(usage)
required = OptionGroup(parser, "Required Arguments")
required.add_option("--genome", dest="genome_file", help="File representing genome. FASTA nucleotide format. ")
required.add_option("--anno", dest="anno_file", help="File containing genome annotation information in GTF/GFF3 format. ")
required.add_option("--output", dest="prefix", help="Creates a folder named with the supplied prefix containing output files. ")
parser.add_option_group(required)
if len(args) != 0 or not options.genome_file or not options.anno_file or not options.prefix:
parser.error("Required arguments have not been supplied. \n\t\tUse -h to get more information.")
sys.exit()
You'll pass the arguments when you run it, for example, with --genome=myfile.txt, and in the code that value becomes options.genome_file.

cv2.videoCapture(filename) assigning filename dynamically (Closed)

I am trying to access file_name dynamically from user and then pass it to videoCapture(file_name) and then process it.
Code :
import cv2
import numpy as np
import os
import sqlite3
import pickle
from PIL import Image
import sys
faceDetect = cv2.CascadeClassifier('haarcascade_frontalface_default.xml');
rec = cv2.createLBPHFaceRecognizer();
'''
Dynamically accessing the fileName
Error seems to be here in the following couple of codes
Note: i am assigning file_name as <"test.mp4">
'''
file_name = raw_input("Enter file name: ")
print file_name
cam = cv2.VideoCapture(file_name)
while cam.isOpened():
ret,img = cam.read()
if ret == True:
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
faces = faceDetect.detectMultiScale(gray,1.3,5);
for(x,y,w,h) in faces :
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
id,conf=rec.predict(gray[y:y+h,x:x+w])
'''
Few lines of code
'''
cv2.imshow("Face",img);
if (cv2.waitKey(1) == ord('q')):
break;
else :
print ('ret is false')
break
cam.release()
cv2.destroyAllWindows()
it show no error but it does not execute the while(cam.isOpened): loop. am i missing something ?
Enter the filename without the quotes. It works fine. Because since the input has alphabets it will be string object already. Adding quotes will be like inputting a wrong file name. As I said in comments videocapture does not throw error sometimes if entered filename does not exist. Hope this helps

Categories