I keep getting an error saying there is no picture when there is. What am I doing wrong? - jython

def blendPictures(pict1, pict2, overlapAmt):
width1 = getWidth(pict1)
height1 = getHeight(pict1)
width2 = getWidth(pict2)
height2 = getHeight(pict2)
newWidth = width1 + width2 - overlapAmt
newHeight = min(height1, height2)
newCanvas = makeEmptyPicture(newWidth, newHeight)
for x in range(width1 - overlapAmt):
for y in range(newHeight):
color = getColor(getPixel(pict1, x, y))
setColor(getPixel(newCanvas, x, y), color)
pict2_x = 0
for pict1_x in range(width1 - overlapAmt, width1):
for y in range(newHeight):
pixel1 = getPixel(pict1, pict1_x, y)
pixel2 = getPixel(pict2, pict2_x, y)
newRed = 0.50 * getRed(pixel1) + 0.50 * getRed(pixel2)
newGreen = 0.50 * getGreen(pixel1) + 0.50 * getGreen(pixel2)
newBlue = 0.50 * getBlue(pixel1) + 0.50 * getBlue(pixel2)
color = makeColor(newRed, newGreen, newBlue)
setColor(getPixel(newCanvas, pict1_x, y), color)
pict2_x = pict2_x + 1
targetX = width1
for x in range(overlapAmt, width2):
for y in range(newHeight):
color = getColor(getPixel(pict2, x, y))
setColor(getPixel(newCanvas, targetX, y), color)
targetX = targetX + 1
return newCanvas
def swapBackground( src, background, newBackground ):
# src, and background must be the same size
# newBackground must be at least as big as src and background
for x in range(1, getWidth( src ) + 1 ) :
for y in range(1, getHeight( src ) + 1 ) :
srcPxl = getPixel( src, x, y )
backgroundPxl = getPixel( background, x, y )
if (distance(getColor( srcPxl ), getColor( backgroundPxl )) < 15.0):
setColor( srcPxl, getColor( getPixel( newBackground, x, y ) ) )
return src
jackalope = blendPictures('rabbit.jpg', 'antelope.jpg', 50)
writePictureTo(jackalope, "./jackalope.jpg")
#here swap the background to place your photo on front
swapBackground( 'photograph.jpg', 'jackalope.jpg', newBackground )
writePictureTo(newBackground, "./nexttojackalope.jpg")
swapBackground( 'rabbit.jpg', 'campus.jpg', newBackground1 )
writePictureTo(newBackground1, "./campustemp.jpg")
swapBackground( 'antelope.jpg', 'campustemp.jpg', newBackground2 )
writePictureTo(newBackground1, "./campusfinal.jpg")
Where the .jpg's are I put where the files will go or where they are pulling from. I have a picture of a rabbit and an antelope with a jackalope wav file and a picture of myself and a picture to put as the background. But I still get an error on line 2 saying that getWidth(picture) isn't defined and I'm not sure what to do. Any ideas?

In order to use the getWidth() function you need to pass a picture object as it's argument. So you will need to first create a picture object using the makePicture() function. For example:
pict1 = makePicture('rabbit.jpg')
width1 = getWidth1(pict1)
Here's a good guide on working with pictures in JES. http://www.cs.bu.edu/courses/cs101b1/jes/#Pictures%20and%20Sound

Related

Update parameters of a function in a while loop

I am trying to execute a while loop that holds a function with parameters. However, I have noticed that the parameters inside the while loop are not updated which leads to an infinite while loop. Is there a reason behind the fact that the function parameters are not being updated after every loop?
import shapefile
from osgeo import gdal
#import rasterio
print (gdal.VersionInfo())
def pointInRect(x, y, x1, y1, w, h): # check if a raster point is in another raster
x2, y2 = x1+w, y1+h
if (x1 < x and x < x2):
if (y1 < y and y < y2):
return True
return False
# Open the shapes centroids
shp_cntrds = 'Path to centroids'
sf_cntrds = shapefile.Reader(shp_cntrds)
shapes_cntrds = sf_cntrds.shapes()
records_cntrds = sf_cntrds.records()
# adjust labels position according to its shapes centroids position
for i in range(len(records_cntrds)):
print(i)
tods = gdal.Open(str(records_cntrds[i][1]))
width = tods.RasterXSize
height = tods.RasterYSize
tods.SetGeoTransform([shapes_cntrds[i].points[0][0] - (width * 0.005), 0.01, 0,
shapes_cntrds[i].points[0][1] + (height * 0.005), 0, -0.01])
gt = tods.GetGeoTransform()
left = gt[0]
bottom = gt[3] + width * gt[4] + height * gt[5]
right = gt[0] + width * gt[1] + height * gt[2]
top = gt[3]
srs = osr.SpatialReference()
srs.SetUTM(32, 1) # set crs
srs.SetWellKnownGeogCS('WGS84') # set crs
tods.SetProjection(srs.ExportToWkt()) # set Projection and save file
print(width, height)
tods = None
# iterate through Labels and move labels away from each others if they overlapp
for i in range(len(records_cntrds)):
tods1 = gdal.Open(str(records_cntrds[i][1])) # records of the centroid shapefile contains the raster file path
width = tods1.RasterXSize
height = tods1.RasterYSize
gt = tods1.GetGeoTransform()
left = gt[0]
bottom = gt[3] + width * gt[4] + height * gt[5]
right = gt[0] + width * gt[1] + height * gt[2]
top = gt[3]
face = [x for x in list(range(len(records_cntrds))) if x != i]
tods1 = None
for j in face:
if str(records_cntrds[i][1]) == str(records_cntrds[j][1]):
pass
else:
ds_raster_face = gdal.Open(str(records_cntrds[j][1]))
#print(str(records_cntrds[i][1]))
#print(str(records_cntrds[j][1]))
gt_face = ds_raster_face.GetGeoTransform()
width_face = ds_raster_face.RasterXSize
height_face = ds_raster_face.RasterYSize
left_face = gt_face[0]
bottom_face = gt_face[3] + width_face * gt_face[4] + height_face * gt_face[5]
right_face = gt_face[0] + width_face * gt_face[1] + height_face * gt_face[2]
top_face = gt_face[3]
width1 = width
left1 = left
height1 = height
bottom1 = bottom
while pointInRect(left_face, bottom_face, left1, bottom1, width1*0.01, height1*0.01) :
tods2 = gdal.Open(str(records_cntrds[i][1]))
gt = tods2.GetGeoTransform()
width1 = tods2.RasterXSize
height1 = tods2.RasterYSize
left1 = gt[0]
bottom1 = gt[3] + width1 * gt[4] + height1 * gt[5]
print("while executed")
tods2.SetGeoTransform([(shapes_cntrds[i].points[0][0] - (width1 * 0.005)) - 2.7, 0.01, 0,
(shapes_cntrds[i].points[0][1] + (height1 * 0.005)) - 2.8, 0, -0.01])
print("coordinates changed to",(i, left1, bottom1, width1, height1))
tods2 = None
The while loop should break when the function return false but it is repeating the same thing. Are the gt values not updatet or are they initialized again ?

Conversion ECEF XYZ to LLH (LAT/LONG/HEIGHT) and translation back - not accurate / possible error in IronPython script

I've modeled a 3D earth with gridpoints, as below:
The points are represented in 3D space as XYZ coordinates.
I then convert XYZ to Lat/Long/Height(elevation) based on the script I took from here:
JSFiddle
For some reason I got really strange results when trying to find XYZ of LLH not from my set, so I tried to verify the initial script by converting XYZ to LLH and then the same LLH back to XYZ to see if I get the same coordinate.
Instead, the resulting coordinate is some XYZ on earth, unrelated to the original XYZ position.
XYZ to LLH script:
Source: JSFiddle
def xyzllh(x,y,z):
""" xyz vector to lat,lon,height
output:
llhvec[3] with components
flat geodetic latitude in deg
flon longitude in deg
altkm altitude in km
"""
dtr = math.pi/180.0
rrnrm = [0.0] * 3
llhvec = [0.0] * 3
geodGBL()
esq = EARTH_Esq
rp = math.sqrt( x*x + y*y + z*z )
flatgc = math.asin( z / rp )/dtr
testval= abs(x) + abs(y)
if ( testval < 1.0e-10):
flon = 0.0
else:
flon = math.atan2( y,x )/dtr
if (flon < 0.0 ):
flon = flon + 360.0
p = math.sqrt( x*x + y*y )
# on pole special case
if ( p < 1.0e-10 ):
flat = 90.0
if ( z < 0.0 ):
flat = -90.0
altkm = rp - rearth(flat)
llhvec[0] = flat
llhvec[1] = flon
llhvec[2] = altkm
return llhvec
# first iteration, use flatgc to get altitude
# and alt needed to convert gc to gd lat.
rnow = rearth(flatgc)
altkm = rp - rnow
flat = gc2gd(flatgc,altkm)
rrnrm = radcur(flat)
rn = rrnrm[1]
for x in range(5):
slat = math.sin(dtr*flat)
tangd = ( z + rn*esq*slat ) / p
flatn = math.atan(tangd)/dtr
dlat = flatn - flat
flat = flatn
clat = math.cos( dtr*flat )
rrnrm = radcur(flat)
rn = rrnrm[1]
altkm = (p/clat) - rn
if ( abs(dlat) < 1.0e-12 ):
break
llhvec[0] = flat
llhvec[1] = flon
llhvec[2] = altkm
return llhvec
# globals
EARTH_A = 0
EARTH_B = 0
EARTH_F = 0
EARTH_Ecc = 0
EARTH_Esq = 0
# starting function do_llhxyz()
CallCount = 0
llh = [0.0] * 3
dtr = math.pi/180
CallCount = CallCount + 1
sans = " \n"
llh = xyzllh(x,y,z)
latitude = llh[0]
longitude= llh[1]
hkm = llh[2]
height = 1000.0 * hkm
latitude = fformat(latitude,5)
longitude = fformat(longitude,5)
height = fformat(height,1)
sans = sans +"Latitude,Longitude, Height (ellipsoidal) from ECEF\n"
sans = sans + "\n"
sans = sans +"Latitude : " + str(latitude) + " deg N\n"
sans = sans +"Longitude : " + str(longitude - 180) + " deg E\n"
sans = sans +"Height : " + str(height) + " m\n"
lats = []
longs = []
heights = []
lats.append(str(latitude))
longs.append(str(longitude - 180))
heights.append(str(height))
And this is the LLH to XYZ script:
Source: www.mathworks.com
a = 6378137
t = 8.1819190842622e-2
# (prime vertical radius of curvature)
N = a / math.sqrt(1 - (t*t) * (math.sin(lat)*math.sin(lat)))
x = []
y = []
z = []
# results:
x.append( ((N+height) * math.cos(lat) * math.cos(long))/1000 )
y.append( ((N+height) * math.cos(lat) * math.sin(long))/1000 )
z.append( (((1-t*t) * N + height) * math.sin(lat))/1000 )
Anyone know what I'm doing wrong here?
Thanks!

RGB to HSV in numpy

I'm trying to implement RGB to HSV conversion from opencv in pure numpy using formula from here:
def rgb2hsv_opencv(img_rgb):
img_hsv = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2HSV)
return img_hsv
def rgb2hsv_np(img_rgb):
assert img_rgb.dtype == np.float32
height, width, c = img_rgb.shape
r, g, b = img_rgb[:,:,0], img_rgb[:,:,1], img_rgb[:,:,2]
t = np.min(img_rgb, axis=-1)
v = np.max(img_rgb, axis=-1)
s = (v - t) / (v + 1e-6)
s[v==0] = 0
# v==r
hr = 60 * (g - b) / (v - t + 1e-6)
# v==g
hg = 120 + 60 * (b - r) / (v - t + 1e-6)
# v==b
hb = 240 + 60 * (r - g) / (v - t + 1e-6)
h = np.zeros((height, width), np.float32)
h = h.flatten()
hr = hr.flatten()
hg = hg.flatten()
hb = hb.flatten()
h[(v==r).flatten()] = hr[(v==r).flatten()]
h[(v==g).flatten()] = hg[(v==g).flatten()]
h[(v==b).flatten()] = hb[(v==b).flatten()]
h[h<0] += 360
h = h.reshape((height, width))
img_hsv = np.stack([h, s, v], axis=-1)
return img_hsv
img_bgr = cv2.imread('00000.png')
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
img_rgb = img_rgb / 255.0
img_rgb = img_rgb.astype(np.float32)
img_hsv1 = rgb2hsv_np(img_rgb)
img_hsv2 = rgb2hsv_opencv(img_rgb)
print('max diff:', np.max(np.fabs(img_hsv1 - img_hsv2)))
print('min diff:', np.min(np.fabs(img_hsv1 - img_hsv2)))
print('mean diff:', np.mean(np.fabs(img_hsv1 - img_hsv2)))
But I get big diff:
max diff: 240.0
min diff: 0.0
mean diff: 0.18085355
Do I missing something?
Also maybe it's possible to write numpy code more efficient, for example without flatten?
Also I have hard time finding original C++ code for cvtColor function, as I understand it should be actually function cvCvtColor from C code, but I can't find actual source code with formula.
From the fact that the max difference is exactly 240, I'm pretty sure that what's happening is in the case when both or either of v==r, v==g are simultaneously true alongside v==b, which gets executed last.
If you change the order from:
h[(v==r).flatten()] = hr[(v==r).flatten()]
h[(v==g).flatten()] = hg[(v==g).flatten()]
h[(v==b).flatten()] = hb[(v==b).flatten()]
To:
h[(v==r).flatten()] = hr[(v==r).flatten()]
h[(v==b).flatten()] = hb[(v==b).flatten()]
h[(v==g).flatten()] = hg[(v==g).flatten()]
The max difference may start showing up as 120, because of that added 120 in that equation. So ideally, you would want to execute these three lines in the order b->g->r. The difference should be negligible then (still noticing a max difference of 0.01~, chalking it up to some round off somewhere).
h[(v==b).flatten()] = hb[(v==b).flatten()]
h[(v==g).flatten()] = hg[(v==g).flatten()]
h[(v==r).flatten()] = hr[(v==r).flatten()]

Can't figure out, why script on Jython working differently from script on Pascal

Long story short: I'm writing script, which should move mouse and do clicks like human (it's a bot, actually), using SikuliX. SikuliX uses Jython 2.7 as lang for scritps.
I found nice lib for my purposes (moving mouse like human): mouse.simba written in Pascal-like lang, and rewrite function _humanWindMouse() in jython. It works, but not like I expected it would be.
Test run of my script, drawing rectangle:
https://prtscr.cx.ua/storage/5b/5b2203.jpg
Result of using original function with same coords:
https://prtscr.cx.ua/storage/bb/bb3ff5.jpg
sorry for links, I can't post images yet (
My code:
import random
import time
import math
from time import sleep
from math import sqrt
from math import ceil
from math import hypot
from java.awt import Robot
def distance(x1, y1, x2, y2):
return math.hypot(x2 - x1, y2 - y1)
def myrandom(x):
return random.randint(0, x-1)
def myround(x):
return int(round(x))
# function MMouseMove (MyMouseMove) for moving mouse using only coord
def MMouseMove(x,y):
robot = Robot()
robot.mouseMove(x,y)
# function HumanWindMouse by BenLand100 & Flight, python implementation
def humanWindMouse(xs, ys, xe, ye, gravity, wind):
veloX = veloY = windX=windY=veloMag=dist=randomDist=lastDist=D=0
lastX=lastY=MSP=W=TDist=0
mouseSpeed = 20
MSP = mouseSpeed
sqrt2 = sqrt(2)
sqrt3 = sqrt(3)
sqrt5 = sqrt(5)
TDist = distance(myround(xs), myround(ys), myround(xe), myround(ye))
t = time.time() + 10000
while True:
if time.time() > t:
break
dist = hypot(xs - xe, ys - ye)
wind = min(wind, dist)
if dist < 1:
dist = 1
D = (myround((myround(TDist)*0.3))/7)
if D > 25:
D = 25
if D < 5:
D = 5
rCnc = myrandom(6)
if rCnc == 1:
D = random.randint(2,3)
if D <= myround(dist):
maxStep = D
else:
maxStep = myround(dist)
windX= windX / sqrt2
windY= windY / sqrt2
veloX= veloX + windX
veloY= veloY + windY
veloX= veloX + gravity * (xe - xs) / dist
veloY= veloY + gravity * (ye - ys) / dist
if hypot(veloX, veloY) > maxStep:
temp = int(myround(maxStep) // 2)
if temp == 0:
temp = 1
randomDist= maxStep / 2.0 + myrandom(temp)
veloMag= sqrt(veloX * veloX + veloY * veloY)
veloX= (veloX / veloMag) * randomDist
veloY= (veloY / veloMag) * randomDist
lastX= myround(xs)
lastY= myround(ys)
xs= xs + veloX
ys= ys + veloY
if lastX <> myround(xs) or lastY <> myround(ys):
MMouseMove(myround(xs), myround(ys))
W = (myrandom((myround(100/MSP)))*6)
if W < 5:
W = 5
W = myround(W*0.9)
sleep(W/1000.0)
lastdist= dist
if hypot(xs - xe, ys - ye) < 1:
break
if myround(xe) <> myround(xs) or myround(ye) <> myround(ys):
MMouseMove(myround(xe), myround(ye))
mouseSpeed = MSP
return;
def MMouse(x,y):
mouseSpeed = 20
randSpeed = (myrandom(mouseSpeed) / 2.0 + mouseSpeed) / 10.0
curPos = Mouse.at()
x1 = curPos.x
y1 = curPos.y
humanWindMouse(x1, y1, x, y, 5, 10.0/randSpeed)
return;
And I used this in such a way:
MMouseMove(227, 146)
mouseDown(Button.LEFT)
MMouse(396, 146)
MMouse(396, 252)
MMouse(227, 252)
MMouse(227, 146)
mouseUp(Button.LEFT)
exit()
mouseDown() and mouseUp() are built-in functions in SikuliX
And I didn't use built-in mouseMove(), because with it going from A to B is too slow.
Any help would be appreciated
After few hours of debugging i figured out the problem: in source code for unknowing reason author passed constant called MOUSE_HUMAN to variable named gravity when caling his function _humanWindMouse(), this looks like an error to me. Thats why I decided to fix this in my code, and throw out one argument of the function and a few lines of code (and that was wrong move). After re-adding needed code my function working, as I expected.
So, here's the working code:
# function HumanWindMouse by BenLand100 & Flight,
# python implementation by Nokse
def humanWindMouse(xs, ys, xe, ye, gravity, wind, targetArea):
veloX = veloY = windX=windY=veloMag=dist=randomDist=lastDist=D=0
lastX=lastY=MSP=W=TDist=0
mouseSpeed = 20
MSP = mouseSpeed
sqrt2 = sqrt(2)
sqrt3 = sqrt(3)
sqrt5 = sqrt(5)
TDist = distance(myround(xs), myround(ys), myround(xe), myround(ye))
t = time.time() + 10000
while True:
if time.time() > t:
break
dist = hypot(xs - xe, ys - ye)
wind = min(wind, dist)
if dist < 1:
dist = 1
D = (myround((myround(TDist)*0.3))/7)
if D > 25:
D = 25
if D < 5:
D = 5
rCnc = myrandom(6)
if rCnc == 1:
D = random.randint(2,3)
if D <= myround(dist):
maxStep = D
else:
maxStep = myround(dist)
if dist >= targetArea:
windX = windX / sqrt3 + (myrandom(myround(wind) * 2 + 1) - wind) / sqrt5
windY = windY / sqrt3 + (myrandom(myround(wind) * 2 + 1) - wind) / sqrt5
else:
windX = windX / sqrt2
windY = windY / sqrt2
veloX = veloX + windX
veloY = veloY + windY
veloX = veloX + gravity * (xe - xs) / dist
veloY = veloY + gravity * (ye - ys) / dist
if hypot(veloX, veloY) > maxStep:
halfSteps = int(myround(maxStep) // 2)
if halfSteps == 0:
halfSteps = 1
randomDist = maxStep / 2.0 + myrandom(halfSteps)
veloMag = sqrt(veloX * veloX + veloY * veloY)
veloX = (veloX / veloMag) * randomDist
veloY = (veloY / veloMag) * randomDist
lastX = myround(xs)
lastY = myround(ys)
xs = xs + veloX
ys = ys + veloY
if lastX <> myround(xs) or lastY <> myround(ys):
MMouseMove(myround(xs), myround(ys))
W = (myrandom((myround(100/MSP)))*6)
if W < 5:
W = 5
W = myround(W*0.9)
sleep(W/1000.0)
lastdist = dist
#condition for exiting while loop
if hypot(xs - xe, ys - ye) < 1:
break
if myround(xe) <> myround(xs) or myround(ye) <> myround(ys):
MMouseMove(myround(xe), myround(ye))
mouseSpeed = MSP
return;
I tested it with different parameters, and choose this one:
humanWindMouse(xs, ys, x, y, 9, 10.0/randSpeed, 10.0*randSpeed)
but I recommend to play with parameters first, to understand, how do they affect the behavior of the mouse.
How to calc randSpeed, what should be imported, and sub-functions, such as myround(), could be found at my first post.
Hope, this code will help somebody someday)

Find control point on piecewise quadratic Bezier curve

I need to write a program to generate and display a piecewise quadratic Bezier curve that interpolates each set of data points (I have a txt file contains data points). The curve should have continuous tangent directions, the tangent direction at each data point being a convex combination of the two adjacent chord directions.
0.1 0,
0 0,
0 5,
0.25 5,
0.25 0,
5 0,
5 5,
10 5,
10 0,
9.5 0
The above are the data points I have, does anyone know what formula I can use to calculate control points?
You will need to go with a cubic Bezier to nicely handle multiple slope changes such as occurs in your data set. With quadratic Beziers there is only one control point between data points and so each curve segment much be all on one side of the connecting line segment.
Hard to explain, so here's a quick sketch of your data (black points) and quadratic control points (red) and the curve (blue). (Pretend the curve is smooth!)
Look into Cubic Hermite curves for a general solution.
From here: http://blog.mackerron.com/2011/01/01/javascript-cubic-splines/
To produce interpolated curves like these:
You can use this coffee-script class (which compiles to javascript)
class MonotonicCubicSpline
# by George MacKerron, mackerron.com
# adapted from:
# http://sourceforge.net/mailarchive/forum.php?thread_name=
# EC90C5C6-C982-4F49-8D46-A64F270C5247%40gmail.com&forum_name=matplotlib-users
# (easier to read at http://old.nabble.com/%22Piecewise-Cubic-Hermite-Interpolating-
# Polynomial%22-in-python-td25204843.html)
# with help from:
# F N Fritsch & R E Carlson (1980) 'Monotone Piecewise Cubic Interpolation',
# SIAM Journal of Numerical Analysis 17(2), 238 - 246.
# http://en.wikipedia.org/wiki/Monotone_cubic_interpolation
# http://en.wikipedia.org/wiki/Cubic_Hermite_spline
constructor: (x, y) ->
n = x.length
delta = []; m = []; alpha = []; beta = []; dist = []; tau = []
for i in [0...(n - 1)]
delta[i] = (y[i + 1] - y[i]) / (x[i + 1] - x[i])
m[i] = (delta[i - 1] + delta[i]) / 2 if i > 0
m[0] = delta[0]
m[n - 1] = delta[n - 2]
to_fix = []
for i in [0...(n - 1)]
to_fix.push(i) if delta[i] == 0
for i in to_fix
m[i] = m[i + 1] = 0
for i in [0...(n - 1)]
alpha[i] = m[i] / delta[i]
beta[i] = m[i + 1] / delta[i]
dist[i] = Math.pow(alpha[i], 2) + Math.pow(beta[i], 2)
tau[i] = 3 / Math.sqrt(dist[i])
to_fix = []
for i in [0...(n - 1)]
to_fix.push(i) if dist[i] > 9
for i in to_fix
m[i] = tau[i] * alpha[i] * delta[i]
m[i + 1] = tau[i] * beta[i] * delta[i]
#x = x[0...n] # copy
#y = y[0...n] # copy
#m = m
interpolate: (x) ->
for i in [(#x.length - 2)..0]
break if #x[i] <= x
h = #x[i + 1] - #x[i]
t = (x - #x[i]) / h
t2 = Math.pow(t, 2)
t3 = Math.pow(t, 3)
h00 = 2 * t3 - 3 * t2 + 1
h10 = t3 - 2 * t2 + t
h01 = -2 * t3 + 3 * t2
h11 = t3 - t2
y = h00 * #y[i] +
h10 * h * #m[i] +
h01 * #y[i + 1] +
h11 * h * #m[i + 1]
y