How do I get indices around certain values in an array - python

So I came accros this tiny but tricky problem.
I have an array of indices of error_images, something like this:
error_frames = [15,27,34,204,205]
Now I am using a for loop to iterate over these frames and add 10 frames in prior and after the erroneous frames in order to get a sequence, so that in the end, the array is more populated. I also removed duplicates (excuse MATLAB writing):
error_sequence = [5:44,194:215]
Now the tricky part:
In Order to show the sequence, I load every image and show it for a certain time using OpenCV cv2.imshow. When actually encountering an error, I want to increase the pause between shown images ('slow motion') and have a special overlay. This looks like this, where frames is a collection of my pictures of the scene:
for x in error_sequence:
if x in error_frames:
cv2.imshow('Sequence', frames[x])
cv2.putText(frames[x], "Error!", (50, 50),
cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 255), 3)
cv2.waitKey(100)
else:
cv2.imshow('Sequence', frames[x])
cv2.waitKey(50)
The problem is, that this "one-frame" overlay is way too fast and I want to slow down more frames, lets say 3 before and after the encountered error.
Is there some kind of function, that lets me do that? Something like:
if x+-3 in error_frames:
...
Thank you for your help and sorry, if this is an easy question, I don't know how else to describe it. And yes, I could come up with an extra array that I set to 0 if it is further away from an error frame than 3 and use a seperate if case, but I don't find that very attractive and was wondering if there is a built in function or a nice "one-liner" ;)

Perhaps something like this:
error_frames_set = set(error_frames)
delta = 3
for x in error_sequence:
slow_frames = set(x + offset for offset in range(-delta, delta+1))
if slow_frames.intersection(error_frames_set):
cv2.imshow('Sequence', frames[x])
cv2.putText(frames[x], "Error!", (50, 50),
cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 255), 3)
cv2.waitKey(100)
else:
cv2.imshow('Sequence', frames[x])
cv2.waitKey(50)

Like so maybe:
if any(y in error_frames for y in xrange(x-3, x+4)):
...
You can consider creating a set out of your error_frames to improve the time complexity of the contains-check:
error_frame_set = set(error_frames)
And then use this set in all the checks.

Related

How to tell if matchTemplate succeeds? [duplicate]

I'm attempting to find an image in another.
im = cv.LoadImage('1.png', cv.CV_LOAD_IMAGE_UNCHANGED)
tmp = cv.LoadImage('e1.png', cv.CV_LOAD_IMAGE_UNCHANGED)
w,h = cv.GetSize(im)
W,H = cv.GetSize(tmp)
width = w-W+1
height = h-H+1
result = cv.CreateImage((width, height), 32, 1)
cv.MatchTemplate(im, tmp, result, cv.CV_TM_SQDIFF)
print result
When I run this, everything executes just fine, no errors get thrown. But I'm unsure what to do from here. The doc says that result stores "A map of comparison results". I tried printing it, but it gives me width, height, and step.
How do I use this information to find whether or not one image is in another/where it is located?
This might work for you! :)
def FindSubImage(im1, im2):
needle = cv2.imread(im1)
haystack = cv2.imread(im2)
result = cv2.matchTemplate(needle,haystack,cv2.TM_CCOEFF_NORMED)
y,x = np.unravel_index(result.argmax(), result.shape)
return x,y
CCOEFF_NORMED is just one of many comparison methoeds.
See: http://docs.opencv.org/doc/tutorials/imgproc/histograms/template_matching/template_matching.html
for full list.
Not sure if this is the best method, but is fast, and works just fine for me! :)
MatchTemplate returns a similarity map and not a location.
You can then use this map to find a location.
If you are only looking for a single match you could do something like this to get a location:
minVal,maxVal,minLoc,maxLoc = cv.MinMaxLoc(result)
Then minLoc has the location of the best match and minVal describes how well the template fits. You need to come up with a threshold for minVal to determine whether you consider this result a match or not.
If you are looking for more than one match per image you need to use algorithms like non-maximum supression.

(hairSimulation/CFX) selecting multiple curves with its own duplicate and blendShape at the same time

In maya I am simulating hair and I want to lock the curves that are jittering. I duplicated those curves to make blend shapes, but there are too many to blend shape them individually. Is there a way to script to solve this? I think the way is to slice to get the name/number of the curves and blendShape all of them with a loop. But since I'm new to scripting I need help.
You can get follicles with this command :
fols = cmds.ls(type='follicle')
After that, find the curves simulated :
crvs = cmds.ls(fols, dag=True, type='nurbsCurve')
Loop through those curves and use :
dup = cmds.duplicate(c)[0] # where c is the iterator of the for loop on crvs
then :
bs = cmds.blendShape(dup, c)
You have few flags on every command but it should help you like name, weight and few more.
I don't have maya for few weeks so I hope it will help you
EDIT :
Not that follicle curves are set as intermediate, for blendshaping, you might need to temporarly set them :
cmds.setAttr(c+'.io', 0)
bs = cmds.blendShape(dup, c)
cmds.setAttr(c+'.io', 1)

Is there a faster way to convert big file from hexa to binary and binary to int?

I have a big DataFrame (1999048 rows and 1col), with hexadecimal datas. I want to put each line in binary, cut it into pieces and traduce each piece in decimal format.
I tried this:
for i in range (len(df.index)):
hexa_line=hex2bin(str(f1.iloc[i]))[::-1]
channel = int(hexa_line[0:3][::-1], 2)
edge = int(hexa_line[3][::-1], 2)
time = int(hexa_line[4:32][::-1], 2)
sweep = int(hexa_line[32:48][::-1], 2)
tag = int(hexa_line[48:63][::-1], 2)
datalost = int(hexa_line[63][::-1], 2)
line=np.array([[channel, edge, time, sweep, tag, datalost]])
tab=np.concatenate((tab, line), axis=0)
But it is really really long.... Is there a faster way to do that ?
only thing I can imagine helping a lot would be changing these lines:
line=np.array([[channel, edge, time, sweep, tag, datalost]])
tab=np.concatenate((tab, line), axis=0)
certainly in pandas, and I think also in numpy concatting is an expensive thing to do, and depends on the size of the total size of both arrays (rather than, say list.append)
I think what this does is re-writes the entire array tab each time you call it. Perhaps you could try appending each line to a list then concatting the whole list together.
eg something more like this:
tab = []
for i in range (len(df.index)):
hexa_line=hex2bin(str(f1.iloc[i]))[::-1]
channel = int(hexa_line[0:3][::-1], 2)
edge = int(hexa_line[3][::-1], 2)
time = int(hexa_line[4:32][::-1], 2)
sweep = int(hexa_line[32:48][::-1], 2)
tag = int(hexa_line[48:63][::-1], 2)
datalost = int(hexa_line[63][::-1], 2)
line=np.array([[channel, edge, time, sweep, tag, datalost]])
tab.append(line)
final_tab = np.concatenate(tab, axis=0)
# or whatever the syntax is :p

google tensor flow crash course. Issues with REPRESENTATION:Programming exercises Task 2: Make Better Use of Latitude

Hi got into another roadblock in tensorflow crashcourse...at the representation programming excercises at this page.
https://developers.google.com/…/repres…/programming-exercise
I'm at Task 2: Make Better Use of Latitude
seems I narrowed the issue to when I convert the raw latitude data into "buckets" or ranges which will be represented as 1 or zero in my feature. The actual code and issue I have is in the paste bin. Any advice would be great! thanks!
https://pastebin.com/xvV2A9Ac
this is to convert the raw latitude data in my pandas dictionary into "buckets" or ranges as google calls them.
LATITUDE_RANGES = zip(xrange(32, 44), xrange(33, 45))
the above code I changed and replaced xrange with just range since xrange is already deprecated python3.
could this be the problem? using range instead of xrange? see below for my conundrum.
def select_and_transform_features(source_df):
selected_examples = pd.DataFrame()
selected_examples["median_income"] = source_df["median_income"]
for r in LATITUDE_RANGES:
selected_examples["latitude_%d_to_%d" % r] = source_df["latitude"].apply(
lambda l: 1.0 if l >= r[0] and l < r[1] else 0.0)
return selected_examples
The next two are to run the above function and convert may exiting training and validation data sets into ranges or buckets for latitude
selected_training_examples = select_and_transform_features(training_examples)
selected_validation_examples = select_and_transform_features(validation_examples)
this is the training model
_ = train_model(
learning_rate=0.01,
steps=500,
batch_size=5,
training_examples=selected_training_examples,
training_targets=training_targets,
validation_examples=selected_validation_examples,
validation_targets=validation_targets)
THE PROBLEM:
oki so here is how I understand the problem. When I run the training model it throws this error
ValueError: Feature latitude_32_to_33 is not in features dictionary.
So I called selected_training_examples and selected_validation_examples
here's what I found. If I run
selected_training_examples = select_and_transform_features(training_examples)
then I get the proper data set when I call selected_training_examples which yields all the feature "buckets" including Feature #latitude_32_to_33
but when I run the next function
selected_validation_examples = select_and_transform_features(validation_examples)
it yields no buckets or ranges resulting in the
`ValueError: Feature latitude_32_to_33 is not in features dictionary.`
so I next tried disabling the first function
selected_training_examples = select_and_transform_features(training_examples)
and I just ran the second function
selected_validation_examples = select_and_transform_features(validation_examples)
If I do this, I then get the desired dataset for
selected_validation_examples .
The problem now is running the first function no longer gives me the "buckets" and I'm back to where I began? I guess my question is how are the two functions affecting each other? and preventing the other from giving me the datasets I need? If I run them together?
Thanks in advance!
a python developer gave me the solution so just wanted to share. LATITUDE_RANGES = zip(xrange(32, 44), xrange(33, 45)) can only be used once the way it was written so I placed it inside the succeding def select_and_transform_features(source_df) function which solved the issues. Thanks again everyone.

ArcGIS 10 python - Conditional statement checking to see if a raster value is in a set

I am attempting to create a raster based on input from another raster.
If a raster value is equal to a number included in a set() than I want it to be 1, else 0
I've attempted the following:
ConfusedRaster = arcpy.Con(inraster in repeatSet, 1, 0)
and
ConfusedRaster = arcpy.Con(inraster, 1, 0, "inraster in repeatSet")
Neither of these work. I believe they don't work because the where clause only accepts Map Algebra expressions: ArcGIS Help
There are two other ways I can think of doing this. One being converting it to a NumPyArray and working with that. The other is looping through the set and creating a raster object for each value in the set. After the loop has finished merge them.
Does anyone have any suggestions or comments on how to go about this?
Thank you
I was searching for an answer to the similar issue and developed a way using the SQL clause in 'ExtractByAttributes'.
repeatList = list(repeatSet)
ras1 = arcpy.sa.ExtractByAttributes(inraster, 'VALUE IN (' + str(repeatList).strip('[]') + ')')
ConfusedRaster = arcpy.sa.Con(arcpy.sa.IsNull(ras1) == 0, 1, 0)

Categories