Trying to run a program in Pycharm - python

I have to test out a code in Pycharm (the bottom of the question), but I cannot figure out how to run it in Pycharm without getting this error:
usage: color.py [-h] -i IMAGE
color.py: error: the following arguments are required: -i/--image
I know that if I was using Idle I would have written this code:
/Users/syedrishad/Downloads/python-project-color-detection/color_detection.py -i
Users/syedrishad/Downloads/python-project-color-detection/colorpic.jpg
But I don't know how to run it on Pycharm
I use a mac and for some reason i always have to put the full path name or it doesn't work.(If that makes a difference)
This program makes it so if I double click on a part of the image, it shows the exact color name. All the color names are stored in this file:
/Users/syedrishad/Downloads/python-project-color-detection/colors.csv
The actual code is here:
import cv2
import numpy as np
import pandas as pd
import argparse
#Creating argument parser to take image path from command line
ap = argparse.ArgumentParser()
ap.add_argument('-i', '--image', required=True, help="Image Path")
args = vars(ap.parse_args())
img_path = args['image']
#Reading the image with opencv
img = cv2.imread(img_path)
#declaring global variables (are used later on)
clicked = False
r = g = b = xpos = ypos = 0
#Reading csv file with pandas and giving names to each column
index=["color","color_name","hex","R","G","B"]
csv = pd.read_csv('colors.csv', names=index, header=None)
#function to calculate minimum distance from all colors and get the most matching color
def getColorName(R,G,B):
minimum = 10000
for i in range(len(csv)):
d = abs(R- int(csv.loc[i,"R"])) + abs(G- int(csv.loc[i,"G"]))+ abs(B- int(csv.loc[i,"B"]))
if(d<=minimum):
minimum = d
cname = csv.loc[i,"color_name"]
return cname
#function to get x,y coordinates of mouse double click
def draw_function(event, x,y,flags,param):
if event == cv2.EVENT_LBUTTONDBLCLK:
global b,g,r,xpos,ypos, clicked
clicked = True
xpos = x
ypos = y
b,g,r = img[y,x]
b = int(b)
g = int(g)
r = int(r)
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_function)
while(1):
cv2.imshow("image",img)
if (clicked):
#cv2.rectangle(image, startpoint, endpoint, color, thickness)-1 fills entire rectangle
cv2.rectangle(img,(20,20), (750,60), (b,g,r), -1)
#Creating text string to display( Color name and RGB values )
text = getColorName(r,g,b) + ' R='+ str(r) + ' G='+ str(g) + ' B='+ str(b)
#cv2.putText(img,text,start,font(0-7),fontScale,color,thickness,lineType )
cv2.putText(img, text,(50,50),2,0.8,(255,255,255),2,cv2.LINE_AA)
#For very light colours we will display text in black colour
if(r+g+b>=600):
cv2.putText(img, text,(50,50),2,0.8,(0,0,0),2,cv2.LINE_AA)
clicked=False
#Break the loop when user hits 'esc' key
if cv2.waitKey(20) & 0xFF ==27:
break
cv2.destroyAllWindows()
If you know how to run, can you please tell me. I have been searching for an answer but come up empty-handed.

As #Yves Daoust mentioned you basically have two options:
A) Either change the code you are testing to provide the required argument or
B) Use Run->Run...->Edit Configurations... to provide the argument as you would from the command line.
Let's examine in more details the options you have:
A) The easiest way would be to provide the path to the image you want to open like this:
# replace img_path = args['image'] with
img_path = 'path/to/the/image'
which has the advantage of being extremely easy to get but it breaks the argparser functionality.
A more versatile solution would be to provide a default parameter and edit this one each time you want to open an image.
import argparse
# Add a global variable here. It will provide the argument if no other is given (via `Run->Run...->Edit Configurations...`)
IMAGE_PATH = 'path/to/image'
#Creating argument parser to take image path from command line
ap = argparse.ArgumentParser()
ap.add_argument('-i', '--image', required=True, help="Image Path", default=IMAGE_PATH)
which has the advantage of keeping the arg parse functionality intact if you are interested in this one.
B) This option means you provide the parameters yourself just like you would do in the console. The parameters are put in the Parameters: field.
For example you could pass:
--image="path/to/image"
PyCharm provides the option to Apply (button) the changes you inserted (which in this case would mean to keep the parameters stored for this script as long as the script will be in the memory).
Hope this clarify things a bit.

You have to go to Run > Run and then select the program you want to run. If it still gives an error, check the file path, otherwise, you have an error in your code. I hope that answers your question.

Related

Custom name for an opencv image (complex name)

hi I want to take a frame from the camera and save it in a folder 'images', I want the image to have name + current timestamp+.jpg , I'm getting error for typing it like this:
cv2.imwrite(os.path.join(path2 , rn), img)
where path2='images'
and rn=str(rightnow.strftime("%I:%M:%p"))
i get this error : could not find a writer for the specified extension in function 'cv::imwrite_'
how can I do it plz , I searched but didn't find an answer and I'm new to python, thanks in advance
The accepted answer is os specific.
What happens if you run the code in Windows?
Assume you have millions of code, are you going to change each slash / with \?
You should use os.path.sep instead of static slash declaration.
First, remove the : in strftime, you can use - or _ or nothing.
rn = str(rightnow.strftime("%I%M%p"))
Second, check whether the path exists, if it doesn't exist, create.
path3 = "".join([path2, os.path.sep, rn])
if not os.path.exists(path3):
os.mkdir(path3)
Third, create the image name
save = "".join([path3, os.path.sep, "image_name.png"])
If you are executing the statement inside the loop, you may use counter
counter += 1
save = "".join([path3, os.path.sep, "image_name{}.png".format(counter)])
Code:
import os
import cv2
from datetime import datetime
path2 = 'img2'
rightnow = datetime.now()
rn = str(rightnow.strftime("%I%M%p"))
img = cv2.imread("1.png")
path3 = "".join([path2, os.path.sep, rn])
if not os.path.exists(path3):
os.mkdir(path3)
save = "".join([path3, os.path.sep, "image_name.png"])
cv2.imwrite(save, img)
Try to change:
cv2.imwrite(os.path.join(path2 , rn), img)
to
cv2.imwrite(os.path.join(path2 , rn)+".jpg", img)

how to use compareHist function opencv

img = cv2.imread('mandrill.png')
histg = cv2.calcHist([img],[0],None,[256],[0,256])
if len (sys.argv) < 2:
print >>sys.stderr, "Usage:", sys.argv[0], "<image>..."
sys.exit (1)
for fn in sys.argv[1:]:
im = cv2.imread (fn)
histr = cv2.calcHist([im],[0],None,[256],[0,256])
a = cv2.compareHist(histr,histg,cv2.cv.CV_COMP_CORREL)
print a
I am trying to use the code above to compare the correlation between histograms histr and histg when I run the code the I get the error
'module' object has no attribute 'cv'
It seems that CV3 the names of the various correlation functions have changed. What are the names of the various correlation functions?
The opencv version you are using has cv2.cv.CV_COMP_CORREL renamed to cv2.HISTCMP_CORREL
The function name changes are as follows (left hand side shows the names for opencv2, right hand side shows the name for the latest version of opencv(opencv3)):
cv2.cv.CV_COMP_CORREL:: cv2.HISTCMP_CORREL
cv2.cv.CV_COMP_CHISQR :: cv2.HISTCMP_CHISQR/ cv2.HISTCMP_CHISQR_ALT
cv2.cv.CV_COMP_INTERSECT :: cv2.HISTCMP_INTERSECT
cv2.cv.CV_COMP_BHATTACHARYYA :: cv2.HISTCMP_BHATTACHARYYA
As Zdar mentioned it looks like the constants have been renamed in opencv3.0 to:
cv2.HISTCMP_CORREL
cv2.HISTCMP_CHISQR
cv2.HISTCMP_INTERSECT
cv2.HISTCMP_BHATTACHARYYA
a = cv2.compareHist(histr,histg,cv2.HISTCMP_CORREL) should work
sample code for compare histogram in OpenCV 3.2
import cv2
path='location_of_images'
im1 = cv2.imread(path+'/'+'first.jpg',0)
hist1 = cv2.calcHist([im1],[0],None,[256],[0,256])
im2 = cv2.imread(path+'/'+'second.jpg',0)
hist2 = cv2.calcHist([im2],[0],None,[256],[0,256])
a=cv2.compareHist(hist1,hist2,cv2.HISTCMP_BHATTACHARYYA)
print a
return value show how close to your test image with compared one.
example: cv2.HISTCMP_BHATTACHARYYA method gives zero(0.0) for the same image.
other methods are cv2.HISTCMP_CHISQR,cv2.HISTCMP_CHISQR_ALT,cv2.HISTCMP_CORREL cv2.HISTCMP_HELLINGER,cv2.HISTCMP_INTERSECT,cv2.HISTCMP_KL_DIV.

im.getcolors() returns None

I am using a simple code to compare an image to a desktop screenshot through the function getcolors() from PIL. When I open an image, it works:
im = Image.open('sprites\Bowser\BowserOriginal.png')
current_sprite = im.getcolors()
print current_sprite
However, using both pyautogui.screenshot() and ImageGrab.grab() for the screenshot, my code returns none. I have tried using the RGB conversion as shown here: Cannot use im.getcolors.
Additionally, even when I save a screenshot to a .png, it STILL returns none.
i = pyautogui.screenshot('screenshot.png')
f = Image.open('screenshot.png')
im = f.convert('RGB')
search_image = im.getcolors()
print search_image
First time posting, help is much appreciated.
Pretty old question but for those who sees this now:
Image.getcolors() takes as a parameter "maxcolors – Maximum number of colors." (from the docs here).
The maximum number of colors an image can have, equals to the number of pixels it contains.
For example, an image of 50*60px will have maximum 3,000 colors.
To translate it into code, try this:
# Open the image.
img = Image.open("test.jpg")
# Set the maxcolors number to the image's pixels number.
colors = img.getcolors(img.size[0]*img.size[1])
If you'd check the docs, getcolors returns None if the number of colors in the image is greater than the default parameter, which is set to 256.

Proper way to use setAttr with channel box selection

please bear with me - I'm new to all this. I tried the searches and have only found bits and pieces to what I'm looking for, but not what I need to connect them.
Basically, I'm trying to create a Python script that allows the user to simply "0" out multiple selected attributes on Maya's Channel box.
So far I have:
import maya.cmds as cmds
selObjs = cmds.ls(sl=1)
selAttrs = cmds.channelBox("mainChannelBox", q=1, sma=1)
print selObjs # returns [u'pCube1']
print selAttrs # returns [u'ty']
If I would like to set the attributes:
cmds.setAttr(selObjs + "." + selAttrs, '0')
of course this is wrong, so how do I properly execute the setAttr command in this sceneario? (The intention includes having to set them if I have multiple selected attributes in the channel box).
I found that in MEL, it works like this. So really I just need help figuring out how to create the python counterpart of this:
string $object[] = `ls -sl`;
string $attribute[] = `channelBox -q -sma mainChannelBox`;
for ($item in $object)
for($attr in $attribute)
setAttr ($item + "." + $attr) 0;
Moving after that, I need an if loop where, if the attribute selected is a scale attribute, the value should be 1 - but this is something I'll look into later, but wouldn't mind being advised on.
Thanks!
So here's what I finally came up with:
import maya.cmds as cmds
selObjs = cmds.ls(sl=1)
selAttrs = cmds.channelBox("mainChannelBox", q=1, sma=1)
scales = ['sy','sx','sz','v']
if not selObjs:
print "no object and attribute is selected!"
elif not selAttrs:
print "no attribute is selected!"
else:
for eachObj in selObjs:
for eachAttr in selAttrs:
if any(scaleVizItem in eachAttr for scaleVizItem in scales):
cmds.setAttr (eachObj+"."+eachAttr, 1)
else:
cmds.setAttr (eachObj+"."+eachAttr, 0)
This will reset the basic transformations to their defaults. Including an if for the scale and visibility values.
I managed to come up with this:
import maya.cmds as cmds
selObjs = cmds.ls(sl=1)
selAttrs = cmds.channelBox("mainChannelBox", q=1, sma=1)
for each in selObjs:
for eachAttr in selAttrs:
cmds.setAttr (each+"."+eachAttr, 0)
And It's working to zero out selected attributes perfectly.
Now im at the stage of figuring out how to get the script to recognize if it contains scale attributes - to change that value to 1 instead of 0. (stuck at how to extract values from a list at the moment)

From Python Code to a Working Executable File (Downsizing Grid Files Program)

I posted a question earlier about a syntax error here Invalid Syntax error in Python Code I copied from the Internet. Fortunately, my problem was fixed really fast thanks to you. However now that there is no syntax error I found myself helpless as I don't know what to do now with this code. As I've said I've done some basic Python Training 3 years ago but the human brain seems to forget things so fast.
So in a few words, I need to reduce the grid resolution of some files to half and I've been searching for a way to do it for weeks. Luckily I found some python code that seems to do exactly what I am looking for. The code is this :
#!/bin/env python
# -----------------------------------------------------------------------------
# Reduce grid data to a smaller size by averaging over cells of specified
# size and write the output as a netcdf file. xyz_origin and xyz_step
# attributes are adjusted.
#
# Syntax: downsize.py <x-cell-size> <y-cell-size> <z-cell-size>
# <in-file> <netcdf-out-file>
#
import sys
import Numeric
from VolumeData import Grid_Data, Grid_Component
# -----------------------------------------------------------------------------
#
def downsize(mode, cell_size, inpath, outpath):
from VolumeData import fileformats
try:
grid_data = fileformats.open_file(inpath)
except fileformats.Uknown_File_Type as e:
sys.stderr.write(str(e))
sys.exit(1)
reduced = Reduced_Grid(grid_data, mode, cell_size)
from VolumeData.netcdf.netcdf_grid import write_grid_as_netcdf
write_grid_as_netcdf(reduced, outpath)
# -----------------------------------------------------------------------------
# Average over cells to produce reduced size grid object.
#
# If the grid data sizes are not multiples of the cell size then the
# final data values along the dimension are not included in the reduced
# data (ie ragged blocks are not averaged).
#
class Reduced_Grid(Grid_Data):
def __init__(self, grid_data, mode, cell_size):
size = map(lambda s, cs: s / cs, grid_data.size, cell_size)
xyz_origin = grid_data.xyz_origin
xyz_step = map(lambda step, cs: step*cs, grid_data.xyz_step, cell_size)
component_name = grid_data.component_name
components = []
for component in grid_data.components:
components.append(Reduced_Component(component, mode, cell_size))
Grid_Data.__init__(self, '', '', size, xyz_origin, xyz_step,
component_name, components)
# -----------------------------------------------------------------------------
# Average over cells to produce reduced size grid object.
#
class Reduced_Component(Grid_Component):
def __init__(self, component, mode, cell_size):
self.component = component
self.mode = mode
self.cell_size = cell_size
Grid_Component.__init__(self, component.name, component.rgba)
# ---------------------------------------------------------------------------
#
def submatrix(self, ijk_origin, ijk_size):
ijk_full_origin = map(lambda i, cs: i * cs, ijk_origin, self.cell_size)
ijk_full_size = map(lambda s, cs: s*cs, ijk_size, self.cell_size)
values = self.component.submatrix(ijk_full_origin, ijk_full_size)
if mode == 'ave':
m = average_down(values, self.cell_size)
I have this saved as a .py file and when I double click it, the command prompt appears for a milisecond and then disappears. I managed to take a screenshot of that command prompt which it says "Unable to create process using 'bin/env python "C:\Users...........py".
What I want to do is to be able to do this downsizing using the Syntax that the code tells me to use :
# Syntax: downsize.py <x-cell-size> <y-cell-size> <z-cell-size>
# <in-file> <netcdf-out-file>
Can you help me ?
Don't run the file by double-clicking it. Run the file by opening a new shell, and typing in the path to the .py file (or just cd to the parent directory) followed by the arguments you want to pass. For example:
python downsize.py 1 2 3 foo bar

Categories