The intention of this program is to take a ppm image and emboss it. (The entire project details can be found here) I am helping with the grading of the assignment and cannot seem to find the student's bug.
The original image I am using looks like this:
the results should look like this:
Here is the entirety of the program (with comments around the problem lines):
# making an image embossed
import numpy
def clamp(color):
if color<0:
return 0
elif color>255:
return 255
else:
return color
def get_num(jen):
variable = ''
ch = gwen.read(1)
while ch.startswith('#'):
while ch!='\n':
ch=gwen.read(1)
while ch.isspace():
ch = gwen.read(1)
while ch.isspace():
ch = gwen.read(1)
while ch.isdigit():
variable = variable + ch
ch=gwen.read(1)
if ch.startswith('#'):
while ch!='\n':
ch=gwen.read(1)
return int(variable)
def emboss(x,y):
d=numpy.empty((h,w*3),numpy.uint8)
print "len x[0]=",len(x[0])
print "len y=", len(y)
print "len y[0]=", len(y[0])
for i in xrange(len(x)):
for j in xrange(0,len(x[0]),3):
for k in xrange(3): #r,g,b loop
#if the next line is used a correct (but not embosed) image results
#d[i][j+k] = x[i][j+k]
sum = 0
for l in xrange(0,3,1):
for m in xrange(0,3,1):
#the next line embosses but causes a triple image in the process
sum = sum + ((x[(i+(l-1))%h][((j+k)+((m-1)*3))%w]) * y[l][m])
#the line below adjusts an embossed images brightness
#if not embossing comment out this line
d[i][j+k]=clamp(sum+127)
return d
name=raw_input('Please enter input name: ')
output= raw_input('Please enter output name: ')
gwen=open(name,"rb")
ch=gwen.read(1)
if ch=='P':
print ('This is P')
else:
print('Error in Header')
ch=gwen.read(1)
if ch=='6':
print ('This is 6')
else:
print('Error in Header')
jen=''
w=get_num(jen)
w=int(w)
print w
h=get_num(jen)
h=int(h)
print h
value=get_num(jen)
value=int(value)
print value
joe=open(output,"wb")
joe.write('P6'+' '+str(w)+' '+str(h)+' '+str(value)+'\n')
a=numpy.fromfile(gwen,numpy.uint8, w*h*3,'')
c=numpy.reshape(a,(h,w*3))
d=numpy.array([[1,1,1],[0,0,0],[-1,-1,-1]])
new=emboss(c,d)
for i in xrange(h):
for j in xrange(0,w*3,3):
r_value = new[i][j]
r=int(clamp(r_value))
g_value = new[i][j+1]
g=int(clamp(g_value))
b_value = new[i][j+2]
b=int(clamp(b_value))
joe.write('%c%c%c'%(r,g,b))
gwen.close()
joe.close()
The problem appears to me to be in the emboss method but I can't seem to fix it. So I included all of it even the part that filters out ppm header comments.
As it is now, it embosses but does a triple image in doing so.
The triple image goes away when the embossing lines are removed.
here is the file I am testing with if you want to try it yourself
Any suggestions of what I should change to fix the bug?
Here's a cleaner version of the emboss function
# renamed
# x -> im (the input image numpy array)
# y -> kernel (the emboss kernel)
# i -> y (the y coordinate)
# j -> x (the x coordinate)
# d -> output (the output numpy array)
# k -> color (the number of the color channel 0-2)
# sum -> sum_ (sum is a built-in, so we shouldn't use that name)
def emboss(im,kernel):
output=numpy.empty((h,w*3),numpy.uint8)
print "len im[0]=",len(im[0])
print "len kernel=", len(kernel)
print "len kernel[0]=", len(kernel[0])
for y in xrange(len(im)):
for x in xrange(0,len(im[0]),3):
for color in xrange(3): #r,g,b loop
#if the next line is used a correct (but not embosed) image results
#output[y][x+color] = im[y][x+color]
sum_ = 0
for l in xrange(0,3,1):
for m in xrange(0,3,1):
#the next line embosses but causes a triple image in the process
sum_ += (im[(y+(l-1))%h][((x+color)+((m-1)*3))%w]) * kernel[l][m]
#the line below adjusts an embossed images brightness
#if not embossing comment out this line
output[y][x+color]=clamp(sum_+127)
return output
The bug seems to be on this line
sum_ += (im[(y+(l-1))%h][((x+color)+((m-1)*3))%w]) * kernel[l][m]
Where the x-coord is moded by w (the image width in pixels). The x-coord varies from 0-1920 (due to the 3 channel colours) whereas the image width is only 640px. moding by (w*3) should correct the problem.
Here is the fix for the original code:
sum = sum + ((x[(i+(l-1))%h][((j+k)+((m-1)*3))%(w*3)]) * y[l][m])
The code need many improvements, but for the bug:
sum = sum + ((x[(i+(l-1))%h][((j+k)+((m-1)*3))%(w*3)]) * y[l][m]) # %(w*3)
Related
I've trying to implement transition from an amount of space to another which is similar to acceleration and deceleration, except i failed and the only thing that i got from this was this infinite stack of mess, here is a screenshot showing this in action:
you can see a very black circle here, which are in reality something like 100 or 200 circles stacked on top of each other
and i reached this result using this piece of code:
def Place_circles(curve, circle_space, cs, draw=True, screen=None):
curve_acceleration = []
if type(curve) == tuple:
curve_acceleration = curve[1][0]
curve_intensity = curve[1][1]
curve = curve[0]
#print(curve_intensity)
#print(curve_acceleration)
Circle_list = []
idx = [0,0]
for c in reversed(range(0,len(curve))):
for p in reversed(range(0,len(curve[c]))):
user_dist = circle_space[curve_intensity[c]] + curve_acceleration[c] * p
dist = math.sqrt(math.pow(curve[c][p][0] - curve[idx[0]][idx[1]][0],2)+math.pow(curve [c][p][1] - curve[idx[0]][idx[1]][1],2))
if dist > user_dist:
idx = [c,p]
Circle_list.append(circles.circles(round(curve[c][p][0]), round(curve[c][p][1]), cs, draw, screen))
This place circles depending on the intensity (a number between 0 and 2, random) of the current curve, which equal to an amount of space (let's say between 20 and 30 here, 20 being index 0, 30 being index 2 and a number between these 2 being index 1).
This create the stack you see above and isn't what i want, i also came to the conclusion that i cannot use acceleration since the amount of time to move between 2 points depend on the amount of circles i need to click on, knowing that there are multiple circles between each points, but not being able to determine how many lead to me being unable to the the classic acceleration formula.
So I'm running out of options here and ideas on how to transition from an amount of space to another.
any idea?
PS: i scrapped the idea above and switched back to my master branch but the code for this is still available in the branch i created here https://github.com/Mrcubix/Osu-StreamGenerator/tree/acceleration .
So now I'm back with my normal code that don't possess acceleration or deceleration.
TL:DR i can't use acceleration since i don't know the amount of circles that are going to be placed between the 2 points and make the time of travel vary (i need for exemple to click circles at 180 bpm of one circle every 0.333s) so I'm looking for another way to generate gradually changing space.
First, i took my function that was generating the intensity for each curves in [0 ; 2]
Then i scrapped the acceleration formula as it's unusable.
Now i'm using a basic algorithm to determine the maximum amount of circles i can place on a curve.
Now the way my script work is the following:
i first generate a stream (multiple circles that need to be clicked at high bpm)
this way i obtain the length of each curves (or segments) of the polyline.
i generate an intensity for each curve using the following function:
def generate_intensity(Circle_list: list = None, circle_space: int = None, Args: list = None):
curve_intensity = []
if not Args or Args[0] == "NewProfile":
prompt = True
while prompt:
max_duration_intensity = input("Choose the maximum amount of curve the change in intensity will occur for: ")
if max_duration_intensity.isdigit():
max_duration_intensity = int(max_duration_intensity)
prompt = False
prompt = True
while prompt:
intensity_change_odds = input("Choose the odds of occurence for changes in intensity (1-100): ")
if intensity_change_odds.isdigit():
intensity_change_odds = int(intensity_change_odds)
if 0 < intensity_change_odds <= 100:
prompt = False
prompt = True
while prompt:
min_intensity = input("Choose the lowest amount of spacing a circle will have: ")
if min_intensity.isdigit():
min_intensity = float(min_intensity)
if min_intensity < circle_space:
prompt = False
prompt = True
while prompt:
max_intensity = input("Choose the highest amount of spacing a circle will have: ")
if max_intensity.isdigit():
max_intensity = float(max_intensity)
if max_intensity > circle_space:
prompt = False
prompt = True
if Args:
if Args[0] == "NewProfile":
return [max_duration_intensity, intensity_change_odds, min_intensity, max_intensity]
elif Args[0] == "GenMap":
max_duration_intensity = Args[1]
intensity_change_odds = Args[2]
min_intensity = Args[3]
max_intensity = Args[4]
circle_space = ([min_intensity, circle_space, max_intensity] if not Args else [Args[0][3],circle_space,Args[0][4]])
count = 0
for idx, i in enumerate(Circle_list):
if idx == len(Circle_list) - 1:
if random.randint(0,100) < intensity_change_odds:
if random.randint(0,100) > 50:
curve_intensity.append(2)
else:
curve_intensity.append(0)
else:
curve_intensity.append(1)
if random.randint(0,100) < intensity_change_odds:
if random.randint(0,100) > 50:
curve_intensity.append(2)
count += 1
else:
curve_intensity.append(0)
count += 1
else:
if curve_intensity:
if curve_intensity[-1] == 2 and not count+1 > max_duration_intensity:
curve_intensity.append(2)
count += 1
continue
elif curve_intensity[-1] == 0 and not count+1 > max_duration_intensity:
curve_intensity.append(0)
count += 1
continue
elif count+1 > 2:
curve_intensity.append(1)
count = 0
continue
else:
curve_intensity.append(1)
else:
curve_intensity.append(1)
curve_intensity.reverse()
if curve_intensity.count(curve_intensity[0]) == len(curve_intensity):
print("Intensity didn't change")
return circle_space[1]
print("\n")
return [circle_space, curve_intensity]
with this, i obtain 2 list, one with the spacing i specified, and the second one is the list of randomly generated intensity.
from there i call another function taking into argument the polyline, the previously specified spacings and the generated intensity:
def acceleration_algorithm(polyline, circle_space, curve_intensity):
new_circle_spacing = []
for idx in range(len(polyline)): #repeat 4 times
spacing = []
Length = 0
best_spacing = 0
for p_idx in range(len(polyline[idx])-1): #repeat 1000 times / p_idx in [0 ; 1000]
# Create multiple list containing spacing going from circle_space[curve_intensity[idx-1]] to circle_space[curve_intensity[idx]]
spacing.append(np.linspace(circle_space[curve_intensity[idx]],circle_space[curve_intensity[idx+1]], p_idx).tolist())
# Sum distance to find length of curve
Length += abs(math.sqrt((polyline[idx][p_idx+1][0] - polyline[idx][p_idx][0]) ** 2 + (polyline [idx][p_idx+1][1] - polyline[idx][p_idx][1]) ** 2))
for s in range(len(spacing)): # probably has 1000 list in 1 list
length_left = Length # Make sure to reset length for each iteration
for dist in spacing[s]: # substract the specified int in spacing[s]
length_left -= dist
if length_left > 0:
best_spacing = s
else: # Since length < 0, use previous working index (best_spacing), could also jsut do `s-1`
if spacing[best_spacing] == []:
new_circle_spacing.append([circle_space[1]])
continue
new_circle_spacing.append(spacing[best_spacing])
break
return new_circle_spacing
with this, i obtain a list with the space between each circles that are going to be placed,
from there, i can Call Place_circles() again, and obtain the new stream:
def Place_circles(polyline, circle_space, cs, DoDrawCircle=True, surface=None):
Circle_list = []
curve = []
next_circle_space = None
dist = 0
for c in reversed(range(0, len(polyline))):
curve = []
if type(circle_space) == list:
iter_circle_space = iter(circle_space[c])
next_circle_space = next(iter_circle_space, circle_space[c][-1])
for p in reversed(range(len(polyline[c])-1)):
dist += math.sqrt((polyline[c][p+1][0] - polyline[c][p][0]) ** 2 + (polyline [c][p+1][1] - polyline[c][p][1]) ** 2)
if dist > (circle_space if type(circle_space) == int else next_circle_space):
dist = 0
curve.append(circles.circles(round(polyline[c][p][0]), round(polyline[c][p][1]), cs, DoDrawCircle, surface))
if type(circle_space) == list:
next_circle_space = next(iter_circle_space, circle_space[c][-1])
Circle_list.append(curve)
return Circle_list
the result is a stream with varying space between circles (so accelerating or decelerating), the only issue left to be fixed is pygame not updating the screen with the new set of circle after i call Place_circles(), but that's an issue i'm either going to try to fix myself or ask in another post
the final code for this feature can be found on my repo : https://github.com/Mrcubix/Osu-StreamGenerator/tree/Acceleration_v02
I'm trying to implement a filter with Python to sort out the points on a point cloud generated by Agisoft PhotoScan. PhotoScan is a photogrammetry software developed to be user friendly but also allows to use Python commands through an API.
Bellow is my code so far and I'm pretty sure there is better way to write it as I'm missing something. The code runs inside PhotoScan.
Objective:
Selecting and removing 10% of points at a time with error within defined range of 50 to 10. Also removing any points within error range less than 10% of the total, when the initial steps of selecting and removing 10% at a time are done. Immediately after every point removal an optimization procedure should be done. It should stop when no points are selectable or when selectable points counts as less than 1% of the present total points and it is not worth removing them.
Draw it for better understanding:
Actual Code Under Construction (3 updates - see bellow for details):
import PhotoScan as PS
import math
doc = PS.app.document
chunk = doc.chunk
# using float with range and that by setting i = 1 it steps 0.1 at a time
def precrange(a, b, i):
if a < b:
p = 10**i
sr = a*p
er = (b*p) + 1
p = float(p)
for n in range(sr, er):
x = n/p
yield x
else:
p = 10**i
sr = b*p
er = (a*p) + 1
p = float(p)
for n in range(sr, er):
x = n/p
yield x
"""
Determine if x is close to y:
x relates to nselected variable
y to p10 variable
math.isclose() Return True if the values a and b are close to each other and
False otherwise
var is the tolerance here setted as a relative tolerance:
rel_tol is the relative tolerance – it is the maximum allowed difference
between a and b, relative to the larger absolute value of a or b. For example,
to set a tolerance of 5%, pass rel_tol=0.05. The default tolerance is 1e-09,
which assures that the two values are the same within about 9 decimal digits.
rel_tol must be greater than zero.
"""
def test_isclose(x, y, var):
if math.isclose(x, y, rel_tol=var): # if variables are close return True
return True
else:
False
# 1. define filter limits
f_ReconstUncert = precrange(50, 10, 1)
# 2. count initial point number
tiePoints_0 = len(chunk.point_cloud.points) # storing info for later
# 3. call Filter() and init it
f = PS.PointCloud.Filter()
f.init(chunk, criterion=PS.PointCloud.Filter.ReconstructionUncertainty)
a = 0
"""
Way to restart for loop!
should_restart = True
while should_restart:
should_restart = False
for i in xrange(10):
print i
if i == 5:
should_restart = True
break
"""
restartLoop = True
while restartLoop:
restartLoop = False
for count, i in enumerate(f_ReconstUncert): # for each threshold value
# count points for every i
tiePoints = len(chunk.point_cloud.points)
p10 = int(round((10 / 100) * tiePoints, 0)) # 10% of the total
f.selectPoints(i) # selects points
nselected = len([p for p in chunk.point_cloud.points if p.selected])
percent = round(nselected * 100 / tiePoints, 2)
if nselected == 0:
print("For threshold {} there´s no selectable points".format(i))
break
elif test_isclose(nselected, p10, 0.1):
a += 1
print("Threshold found in iteration: ", count)
print("----------------------------------------------")
print("# {} Removing points from cloud ".format(a))
print("----------------------------------------------")
print("# {}. Reconstruction Uncerntainty:"
" {:.2f}".format(a, i))
print("{} - {}"
" ({:.1f} %)\n".format(tiePoints,
nselected, percent))
f.removePoints(i) # removes points
# optimization procedure needed to refine cameras positions
print("--------------Optimizing cameras-------------\n")
chunk.optimizeCameras(fit_f=True, fit_cx=True,
fit_cy=True, fit_b1=False,
fit_b2=False, fit_k1=True,
fit_k2=True, fit_k3=True,
fit_k4=False, fit_p1=True,
fit_p2=True, fit_p3=False,
fit_p4=False, adaptive_fitting=False)
# count again number of points in point cloud
tiePoints = len(chunk.point_cloud.points)
print("= {} remaining points after"
" {} removal".format(tiePoints, a))
# reassigning variable to get new 10% of remaining points
p10 = int(round((10 / 100) * tiePoints, 0))
percent = round(nselected * 100 / tiePoints, 2)
print("----------------------------------------------\n\n")
# restart loop to investigate from range start
restartLoop = True
break
else:
f.resetSelection()
continue # continue to next i
else:
f.resetSelection()
print("for loop didnt work out")
print("{} iterations done!".format(count))
tiePoints = len(chunk.point_cloud.points)
print("Tiepoints 0: ", tiePoints_0)
print("Tiepoints 1: ", tiePoints)
Problems:
A. Currently I'm stuck on an endless processing because of a loop. I know it's about my bad coding. But how do I implement my objective and get away with the infinite loops? ANSWER: Got the code less confusing and updated above.
B. How do I start over (or restart) my search for valid threshold values in the range(50, 20) after finding one of them? ANSWER: Stack Exchange: how to restart a for loop
C. How do I turn the code more pythonic?
IMPORTANT UPDATE 1: altered above
Using a better range with float solution adapted from stackoverflow: how-to-use-a-decimal-range-step-value
# using float with range and that by setting i = 1 it steps 0.1 at a time
def precrange(a, b, i):
if a < b:
p = 10**i
sr = a*p
er = (b*p) + 1
p = float(p)
return map(lambda x: x/p, range(sr, er))
else:
p = 10**i
sr = b*p
er = (a*p) + 1
p = float(p)
return map(lambda x: x/p, range(sr, er))
# some code
f_ReconstUncert = precrange(50, 20, 1)
And also using math.isclose() to determine if selected points are close to the 10% selected points instead of using a manual solution through assigning new variables. This was implemented as follows:
"""
Determine if x is close to y:
x relates to nselected variable
y to p10 variable
math.isclose() Return True if the values a and b are close to each other and
False otherwise
var is the tolerance here setted as a relative tolerance:
rel_tol is the relative tolerance – it is the maximum allowed difference
between a and b, relative to the larger absolute value of a or b. For example,
to set a tolerance of 5%, pass rel_tol=0.05. The default tolerance is 1e-09,
which assures that the two values are the same within about 9 decimal digits.
rel_tol must be greater than zero.
"""
def test_threshold(x, y, var):
if math.isclose(x, y, rel_tol=var): # if variables are close return True
return True
else:
False
# some code
if test_threshold(nselected, p10, 0.1):
# if true then a valid threshold is found
# some code
UPDATE 2: altered on code under construction
Minor fixes and got to restart de for loop from beginning by following guidance from another Stack Exchange post on the subject. Have to improve the range now or alter the isclose() to get more values.
restartLoop = True
while restartLoop:
restartLoop = False
for i in range(0, 10):
if condition:
restartLoop = True
break
UPDATE 3: Code structure to achieve listed objectives:
threshold = range(0, 11, 1)
listx = []
for i in threshold:
listx.append(i)
restart = 0
restartLoop = True
while restartLoop:
restartLoop = False
for idx, i in enumerate(listx):
print("do something as printing i:", i)
if i > 5: # if this condition restart loop
print("found value for condition: ", i)
del listx[idx]
restartLoop = True
print("RESTARTING LOOP\n")
restart += 1
break # break inner while and restart for loop
else:
# continue if the inner loop wasn't broken
continue
else:
continue
print("restart - outer while", restart)
Actually an image is descretized into 3 bins (0,1,2) .So any color that falls into particular bin is replaced with the bin no.Therefore discretized image can be viewed as this matrix:
a=[[2,1,2,2,1,1],
[2,2,1,2,1,1],
[2,1,3,2,1,1],
[2,2,2,1,1,2],
[2,2,1,1,2,2],
[2,2,1,1,2,2]]
The next step is to compute the connected components. Individual components will be labeled with letters (A;B;C;D;E;F etc) and we will need to keep a table which maintains the discretized color associated with each label, along with the number of pixels with that label. Of course, the same discretized color can be associated with different labels if multiple contiguous regions of the same color exist. The image may then become
b=[[B,C,B,B,A,A],
[B,B,C,B,A,A],
[B,C,D,B,A,A],
[B,B,B,A,A,E],
[B,B,A,A,E,E],
[B,B,A,A,E,E]]
and the connected components table will be:
Label A B C D E
Color 1 2 1 3 1
Size 12 15 3 1 5
Let q=4.The components A, B, and E have more than q pixels, and the components C and D less than q pixels. Therefore the pixels in A;B and E are classied as coherent, while the pixels in C and D are classied as incoherent. The CCV for this image will be
Color : 1 2 3
coherent: 17 15 0
incoherent: 3 0 1
A given color bucket may thus contain only coherent pixels (as does 2), only incoherent pixels
(as does 3), or a mixture of coherent and incoherent pixels (as does 1). If we assume there are only 3 possible discretized colors, the CCV can also be written as
<(17; 3) ; (15; 0) ; (0; 1)>
for three colors
Please anybody help me with the algorithm for finding connected components
I have implemented iterative dfs and recursive dfs ,but both seem to be inefficient ,they take nearly 30 minutes to compute connected components of an image.Anybody help me how to find it ?I'm running out of time I have to submit my project. I'm pasting both my codes:
Image size:384*256
code using recursive dfs:
import cv2
import sys
from PIL import Image
import ImageFilter
import numpy
import PIL.Image
from numpy import array
stack=[]
z=0
sys.setrecursionlimit(9000000)
def main():
imageFile='C:\Users\Abhi\Desktop\cbir-p\New folder\gray_image.jpg'
size = Image.open(imageFile).size
print size
im=Image.open(imageFile)
inimgli=[]
for x in range(size[0]):
inimgli.append([])
for y in range(size[1]):
inten=im.getpixel((x,y))
inimgli[x].append(inten)
for item in inimgli:
item.insert(0,0)
item.append(0)
inimgli.insert(0,[0]*len(inimgli[0]))
inimgli.append([0]*len(inimgli[0]))
blurimg=[]
for i in range(1,len(inimgli)-1):
blurimg.append([])
for j in range(1,len(inimgli[0])-1):
blurimg[i-1].append((inimgli[i-1][j-1]+inimgli[i-1][j]+inimgli[i-1][j+1]+inimgli[i][j-1]+inimgli[i][j]+inimgli[i][j+1]+inimgli[i+1][j-1]+inimgli[i+1][j]+inimgli[i+1][j+1])/9)
#print blurimg
displi=numpy.array(blurimg).T
im1 = Image.fromarray(displi)
im1.show()
#i1.save('gray.png')
descretize(blurimg)
def descretize(rblurimg):
count=-1
desc={}
for i in range(64):
descli=[]
for t in range(4):
count=count+1
descli.append(count)
desc[i]=descli
del descli
#print len(rblurimg),len(rblurimg[0])
#print desc
drblur=[]
for x in range(len(rblurimg)):
drblur.append([])
for y in range(len(rblurimg[0])):
for item in desc:
if rblurimg[x][y] in desc[item]:
drblur[x].append(item)
#displi1=numpy.array(drblur).T
#im1 = Image.fromarray(displi1)
#im1.show()
#im1.save('xyz.tif')
#print drblur
connected(drblur)
def connected(rdrblur):
table={}
#print len(rdrblur),len(rdrblur[0])
for item in rdrblur:
item.insert(0,0)
item.append(0)
#print len(rdrblur),len(rdrblur[0])
rdrblur.insert(0,[0]*len(rdrblur[0]))
rdrblur.append([0]*len(rdrblur[0]))
copy=[]
for item in rdrblur:
copy.append(item[:])
global z
count=0
for i in range(1,len(rdrblur)-1):
for j in range(1,len(rdrblur[0])-1):
if (i,j) not in stack:
if rdrblur[i][j]==copy[i][j]:
z=0
times=dfs(i,j,str(count),rdrblur,copy)
table[count]=(rdrblur[i][j],times+1)
count=count+1
#z=0
#times=dfs(1,255,str(count),rdrblur,copy)
#print times
#print stack
stack1=[]
#copy.pop()
#copy.pop(0)
#print c
#print table
for item in table.values():
stack1.append(item)
#print stack1
table2={}
for v in range(64):
table2[v]={'coherent':0,'incoherent':0}
#for item in stack1:
# if item[0] not in table2.keys():
# table2[item[0]]={'coherent':0,'incoherent':0}
for item in stack1:
if item[1]>300:
table2[item[0]]['coherent']=table2[item[0]]['coherent']+item[1]
else:
table2[item[0]]['incoherent']=table2[item[0]]['incoherent']+item[1]
print table2
#return table2
def dfs(x,y,co,b,c):
dx = [-1,-1,-1,0,0,1,1,1]
dy = [-1,0,1,-1,1,-1,0,1]
global z
#print x,y,co
c[x][y]=co
stack.append((x,y))
#print dx ,dy
for i in range(8):
nx = x+(dx[i])
ny = y+(dy[i])
#print nx,ny
if b[x][y] == c[nx][ny]:
dfs(nx,ny,co,b,c)
z=z+1
return z
if __name__ == '__main__':
main()
iterative dfs:
def main():
imageFile='C:\Users\Abhi\Desktop\cbir-p\New folder\gray_image.jpg'
size = Image.open(imageFile).size
print size
im=Image.open(imageFile)
inimgli=[]
for x in range(size[0]):
inimgli.append([])
for y in range(size[1]):
inten=im.getpixel((x,y))
inimgli[x].append(inten)
for item in inimgli:
item.insert(0,0)
item.append(0)
inimgli.insert(0,[0]*len(inimgli[0]))
inimgli.append([0]*len(inimgli[0]))
blurimg=[]
for i in range(1,len(inimgli)-1):
blurimg.append([])
for j in range(1,len(inimgli[0])-1):
blurimg[i-1].append((inimgli[i-1][j-1]+inimgli[i-1][j]+inimgli[i-1][j+1]+inimgli[i][j-1]+inimgli[i][j]+inimgli[i][j+1]+inimgli[i+1][j-1]+inimgli[i+1][j]+inimgli[i+1][j+1])/9)
#print blurimg
#displi=numpy.array(blurimg).T
#im1 = Image.fromarray(displi)
#im1.show()
#i1.save('gray.png')
descretize(blurimg)
def descretize(rblurimg):
count=-1
desc={}
for i in range(64):
descli=[]
for t in range(4):
count=count+1
descli.append(count)
desc[i]=descli
del descli
#print len(rblurimg),len(rblurimg[0])
#print desc
drblur=[]
for x in range(len(rblurimg)):
drblur.append([])
for y in range(len(rblurimg[0])):
for item in desc:
if rblurimg[x][y] in desc[item]:
drblur[x].append(item)
#displi1=numpy.array(drblur).T
#im1 = Image.fromarray(displi1)
#im1.show()
#im1.save('xyz.tif')
#print drblur
connected(drblur)
def connected(rdrblur):
for item in rdrblur:
item.insert(0,0)
item.append(0)
#print len(rdrblur),len(rdrblur[0])
rdrblur.insert(0,[0]*len(rdrblur[0]))
rdrblur.append([0]*len(rdrblur[0]))
#print len(rdrblur),len(rdrblur[0])
copy=[]
for item in rdrblur:
copy.append(item[:])
count=0
#temp=0
#print len(alpha)
for i in range(1,len(rdrblur)-1):
for j in range(1,len(rdrblur[0])-1):
if (i,j) not in visited:
dfs(i,j,count,rdrblur,copy)
count=count+1
print "success"
def dfs(x,y,co,b,c):
global z
#print x,y,co
stack=[]
c[x][y]=str(co)
visited.append((x,y))
stack.append((x,y))
while len(stack) != 0:
exstack=find_neighbors(stack.pop(),co,b,c)
stack.extend(exstack)
#print visited
#print stack
#print len(visited)
#print c
'''while (len(stack)!=0):
(x1,y1)=stack.pop()
exstack=find_neighbors(x1,y1)
stack.extend(exstack)'''
def find_neighbors((x2,y2),cin,b,c):
#print x2,y2
neighborli=[]
for i in range(8):
x=x2+(dx[i])
y=y2+(dy[i])
if (x,y) not in visited:
if b[x2][y2]==b[x][y]:
visited.append((x,y))
c[x][y]=str(cin)
neighborli.append((x,y))
return neighborli
if __name__ == '__main__':
main()
Here's another post I have answered which doing exactly the same thing
which include a sample code using simply DFS.
How do I find the connected components in a binary image?
Modify the DFS function: add one parameter current_color = {0,1,2}, so that you can decide if you can go to another node from this node or not. (If the nabouring node has same color with current_color and not yet visit, recurssively visit that node)
The DFS is good algorithm but the recursive algorithm is space inefficient and non recursive one is very complex so I would advice connected component labelling algorithm which uses disjoint-set datastructure in two pass to get solution in non recursive way in linear time.
Note: Use image processing libraries for the same as they do have parallel fast implementation.
I had a similar issue, but in 3D, and asked a question about that here:
Increasing efficiency of union-find
I found the union-find algorithm to be much faster than anything else for my case (which makes sense given the complexity)
So I have a code that gives an output, and what I need to do is pull the information out in between the commas, assign them to a variable that changes dynamically when called... here is my code:
import re
data_directory = 'Z:/Blender_Roto/'
data_file = 'diving_board.shape4ae'
fullpath = data_directory + data_file
print("====init=====")
file = open(fullpath)
for line in file:
current_line = line
# massive room for optimized code here.
# this assumes the last element of the line containing the words
# "Units Per Second" is the number we are looking for.
# this is a non float number, generally.
if current_line.find("Units Per Second") != -1:
fps = line_split = float(current_line.split()[-1])
print("Frames Per Second:", fps)
# source dimensions
if current_line.find("Source Width") != -1:
source_width = line_split = int(current_line.split()[-1])
print("Source Width:", source_width)
if current_line.find("Source Height") != -1:
source_height = line_split = int(current_line.split()[-1])
print("Source Height:", source_height)
# aspect ratios
if current_line.find("Source Pixel Aspect Ratio") != -1:
source_px_aspect = line_split = int(current_line.split()[-1])
print("Source Pixel Aspect Ratio:", source_px_aspect)
if current_line.find("Comp Pixel Aspect Ratio") != -1:
comp_aspect = line_split = int(current_line.split()[-1])
print("Comp Pixel Aspect Ratio:", comp_aspect)
# assumption, ae file can contain multiple mocha shapes.
# without knowing the exact format i will limit the script
# to deal with one mocha shape being animated N frames.
# this gathers the shape details, and frame number but does not
# include error checking yet.
if current_line.find("XSpline") != -1:
# record the frame number.
frame = re.search("\s*(\d*)\s*XSpline", current_line)
if frame.group(1) != None:
frame = frame.group(1)
print("frame:", frame)
# pick part the part of the line that deals with geometry
match = re.search("XSpline\((.+)\)\n", current_line)
line_to_strip = match.group(1)
points = re.findall('(\(.*?\))', line_to_strip)
print(len(points))
for point in points:
print(point)
print("="*40)
file.close()
This gives me the output:
====init=====
Frames Per Second: 24.0
Source Width: 2048
Source Height: 778
Source Pixel Aspect Ratio: 1
Comp Pixel Aspect Ratio: 1
frame: 20
5
(0.793803,0.136326,0,0.5,0)
(0.772345,0.642332,0,0.5,0)
(0.6436,0.597615,0,0.5,0)
(0.70082,0.143387,0,0.5,0.25)
(0.70082,0.112791,0,0.5,0)
========================================
So what I need for example is to be able to assign (0.793803, 0.136326, 0, 0.5, 0) to (1x,1y,1z,1w,1s), (0.772345,0.642332,0,0.5,0) to (2x, 2y, 2z, 2w, 2s) etc so that no matter what numbers are filling those positions they will take on that value.
here is the code I need to put those numbers into:
#-------------------------------------------------------------------------------
# Name: Mocha Rotoscoping Via Blender
# Purpose: Make rotoscoping more efficient
#
# Author: Jeff Owens
#
# Created: 11/07/2011
# Copyright: (c) jeff.owens 2011
# Licence: Grasshorse
#-------------------------------------------------------------------------------
#!/usr/bin/env python
import sys
import os
import parser
sys.path.append('Z:\_protomotion\Prog\HelperScripts')
import GetDir
sys.path.append('Z:\_tutorials\01\tut01_001\prod\Blender_Test')
filename = 'diving_board.shape4ae'
infile = 'Z:\_tutorials\01\tut01_001\prod\Blender_Test'
import bpy
from mathutils import Vector
#below are taken from mocha export
x_width =2048
y_height = 778
z_depth = 0
frame = 20
def readText():
text_file = open('diving_board.shape4ae', 'r')
lines = text_file.readlines()
print (lines)
print (len.lines)
for line in lines:
print (line)
##sets points final x,y,z value taken from mocha export for blender interface
point1x = (0.642706 * x_width)
point1y = (0.597615 * y_height)
point1z = (0 * z_depth)
point2x = (0.770557 * x_width)
point2y = (0.647039 * y_height)
point2z = (0 * z_depth)
point3x = (0.794697 * x_width)
point3y = (0.0869024 * y_height)
point3z = (0 * z_depth)
point4x = (0.707973* x_width)
point4y = (0.0751348 * y_height)
point4z = (0 * z_depth)
w = 1 # weight
listOfVectors = [Vector((point1x,point1y,point1z)),Vector((point2x,point2y,point2z)),Vector((point3x,point3 y,point3z)),Vector((point4x,point4y,point4z)), Vector((point1x,point1y,point1z))]
def MakePolyLine(objname, curvename, cList):
curvedata = bpy.data.curves.new(name=curvename, type='CURVE')
curvedata.dimensions = '3D'
objectdata = bpy.data.objects.new(objname, curvedata)
objectdata.location = (0,0,0) #object origin
bpy.context.scene.objects.link(objectdata)
polyline = curvedata.splines.new('POLY')
polyline.points.add(len(cList)-1)
for num in range(len(cList)):
x, y, z = cList[num]
polyline.points[num].co = (x, y, z, w)
MakePolyLine("NameOfMyCurveObject", "NameOfMyCurve", listOfVectors)
So where I have my vector I would like to be able to place (p.x, p.y,0.z,p.w,p.s) then (p2.x,p2.y,p2.zp2.wp2.s) etc so that it can change per the number given
Any help will be great.. thank you in advance!
-jeff
Instead of printing each output, you can create point objects and index them by name. For example:
>>> class Point:
... def __init__(self, t):
... (self.x,self.y,self.z,self.w,self.s) = t
...
>>> p = Point( (3,4,5,3,1) )
>>> p.w
3
You can place these point objects in an array, then access components by
myPoints[3].x
ADDENDUM
If it is important to you not to pull the points from an array, but rather use actual variable names, you can do the following, where points is your array of tuples:
(p0x,p0y,p0z,p0w,p0s) = points[0]
(p1x,p1y,p1z,p1w,p1s) = points[1]
(p2x,p2y,p2z,p2w,p2s) = points[2]
...
and so on.
Do consider whether this is an appropriate approach though. Having a point class allows you to have any number of points. With defined variable names, creating an unbounded number of these things on the fly is possible but almost always a bad idea. Here is a caveat about doing so: http://mail.python.org/pipermail/tutor/2005-January/035232.html.
When you have an array of point objects you do what you want much better! For example you can do the following:
myPoints[i].y = 12
thereby changing the y-coordinate of the ith point. This is next to impossible when you have fixed the variable names. Hope that helps! (And hope I understand your clarification! Let me know if not....)
If I'm reading your code right, the relevant portion is the loop at the end that produces your tuples.
data = []
for point in points:
data.append(point)
print(point)
That will create a new list and add each tuple to the list. So, data[0] holds (0.793803,0.136326,0,0.5,0) and data[0][0] holds 0.793803.
Here is the code:
#!/usr/bin/env python
import json
import sys
import os
import parser
sys.path.append('Z:\_protomotion\Prog\HelperScripts')
import GetDir
sys.path.append('Z:/Blender_Roto')
filename = 'diving_board.shape4ae'
infile = 'Z:/Blender_Roto/'
#import bpy
#from mathutils import Vector
#below are taken from mocha export
x_width =2048
y_height = 778
z_depth = 0
frame = 20
import re
data_directory = 'Z:/Blender_Roto/' # windows
data_file = 'diving_board.shape4ae'
fullpath = data_directory + data_file
print("====init=====")
file = open(fullpath)
for line in file:
current_line = line
# massive room for optimized code here.
# this assumes the last element of the line containing the words
# "Units Per Second" is the number we are looking for.
# this is a non float number, generally.
if current_line.find("Units Per Second") != -1:
fps = line_split = float(current_line.split()[-1])
print("Frames Per Second:", fps)
# source dimensions
if current_line.find("Source Width") != -1:
source_width = line_split = int(current_line.split()[-1])
print("Source Width:", source_width)
if current_line.find("Source Height") != -1:
source_height = line_split = int(current_line.split()[-1])
print("Source Height:", source_height)
# aspect ratios
if current_line.find("Source Pixel Aspect Ratio") != -1:
source_px_aspect = line_split = int(current_line.split()[-1])
print("Source Pixel Aspect Ratio:", source_px_aspect)
if current_line.find("Comp Pixel Aspect Ratio") != -1:
comp_aspect = line_split = int(current_line.split()[-1])
print("Comp Pixel Aspect Ratio:", comp_aspect)
# assumption, ae file can contain multiple mocha shapes.
# without knowing the exact format i will limit the script
# to deal with one mocha shape being animated N frames.
# this gathers the shape details, and frame number but does not
# include error checking yet.
if current_line.find("XSpline") != -1:
# record the frame number.
print(len(points))
frame = re.search("\s*(\d*)\s*XSpline", current_line)
if frame.group(1) != None:
frame = frame.group(1)
print("frame:", frame)
# pick part the part of the line that deals with geometry
match = re.search("XSpline\((.+)\)\n", current_line)
line_to_strip = match.group(1)
points = re.findall('(\(.*?\))', line_to_strip)
(p1, p2, p3, p4, p5) = points
print (p1)
#print (p2)
#print (p3)
#print (p4)
#print (p5)
file.close()
Here is my output:
====init=====
Frames Per Second: 24.0
Source Width: 2048
Source Height: 778
Source Pixel Aspect Ratio: 1
Comp Pixel Aspect Ratio: 1
5
frame: 20
(0.793803,0.136326,0,0.5,0)
from this output I want to be able to assign (0.793803) to the variable 'point1x' (0.136326) to the variable point1y (0) to the variable point1z (0.5) to the variable point1w and (0) to the variable point1s.
So instead of just outputting (0.793803,0.136326,0,0.5,0) I want it to give me the values individually
so:
point1x: 0.793803
point1y: 0.136326
point1z: 0
point1w: 0.5
point1s: 0
Anyone know how I can do this?
That looks like a tuple, in which case, the python statement for what you want is:
point1x, point1y, point1z, point1w = (0.793803,0.136326,0,0.5,0)
Once you have points, if you know it will always be a comma-seperated list of decimal numbers, simply do something like this:
points = points.split(",")
# points = ["0.793803","0.136326","0","0.5","0"]
# Now you can use John Gaines suggestion
# to unpack your variables
point1x, point1y, point1z, point1w = points
If you don't know how many points there will be to unpack for any given entry, but you know the max, simply check points length after you split and add the appropriate number of None entries to the list:
# Somewhere earlier
max_entries = 5
# ... snip ...
# points = ["0.793803","0.136326","0"]
cur_len = len(points)
if cur_len > max_entries:
raise ValueError("%d points discovered in %s. Max entries is %d" % (cur_len, points, max_entries)
if cur_len != max_entries:
points += [None] * (max_entries - cur_len)
# Continue from here