Function is only performed for the last iteration in a while loop
Question:
I have a program that analyzes fish behavior and categorizes it, giving each behavior a number between 1-80. Then, my code groups the frames in which their behaviors took place for at least 50 seconds. I end up with a csv file that looks like this. Note that mean = Behavior:
Example of behaviors analyzed in Fish 1_1:
behavior
first
last
len
0
7
32
87
1
19
277
333
2
1
785
940
3
30
4062
4125
4
29
4214
4269
5
7
4450
4599
6
1
4612
4775
7
7
4778
4882
8
8
4945
4999
My code is meant to focus on a specific fish and crop the video frames from the first frame of a specific behavior until the last frame of the behavior, then do the same for the next behavior of that fish in a loop.
For some reason, my code only crops frames with the last behavior of fish 8_10, which is the last fish. Lately, I have added the for loops and the try/except.
Why is this starting at fish 8_10 instead of fish 1_1?
Thanks!
import os
import pandas as pd
import cv2
import math
#####Generating avi files with roi being specific fish, for frame ranges where behaviors are consistent for at least 1 second or 50 frames
for ro in range(8): # iterate through the rows, 8 rows total
for col in range(10): # interate through the columns, 10 columns total
try:
# Starting and ending frames, length of video in frames
os.chdir("C:\****\BN4 A4-F4, H4\%d_%d" % (ro+1, col+1))
df4 = pd.read_csv("BN4 A4-F4, H4_row%d_column%d Behaviors.csv" % (ro+1,col+1), names=['mean','first', 'last', 'len'], skiprows=2)
except:
continue
def apply_each_behavior(row):
# Dimension for cropping out each fish
box_dim = 220
# Set parameters for locating each ZeChat unit as ROIs for cropping
y_orig = 25
x_orig = 20
wall = 20
window = 15
# locate the roi so that each cell can be selected by just changing the row and column number:
y_roi = y_orig+(box_dim*(ro))+(window*int(math.ceil(ro/2)))+(wall*(int(math.ceil((ro+1)/2))-1))
x_roi = x_orig+(box_dim*(col))+(wall*col)
# Identifies the value in each row and column as the function is applied
Behavior = row['mean']
starting_frame = row['first']
ending_frame = row['last']
length = row['len']
os.chdir("C:\****")
cap = cv2.VideoCapture("BN4 A4-F4, H4.avi")
#****** Code for what I do with the videos, not relevant to the question*****
cap.release()
cv2.destroyAllWindows()
df4.apply(apply_each_behavior, axis=1)
Here is an example of some of the output:
Opening BN4 A4-F4, H4.avi
Opening video BN4 A4-F4, H4.avi
Frame Rate : 50 frames per second
Frame count : 46728.0
....
Writing video for Behavior 32, fish 8_10, frames 1856-1969, length 114, BN4 A4-F4 H4.avi
The following numbers should be identical:
counter: 114 frames
length: 114 frames
0 None
1 None
2 None
3 None
dtype: object
Answers:
I figured it out. The issues was in where I had the except. I was essentially telling it to iterate through the list, and at the end of the list then run the function. Here is the fixed code:
for ro in range(8): # iterate through the rows, 8 rows total
for col in range(10): # interate through the columns, 10 columns total
try:
# Opening the behavior files if they are found, 2_9 and 5_10 do not have an original data file, so they do not have a behavior file
os.chdir("C:\****\BN4 A4-F4, H4\%d_%d" % (ro+1, col+1))
df4 = pd.read_csv("BN4 A4-F4, H4_row%d_column%d Behaviors.csv" % (ro+1,col+1), names=['mean','first', 'last', 'len'], skiprows=2)
def apply_each_behavior(row):
# Dimension for cropping out each fish
box_dim = 220
# Set parameters for locating each ZeChat unit as ROIs for cropping
y_orig = 25
x_orig = 20
wall = 20
window = 15
# locate the roi so that each cell can be selected by just changing the row and column number:
y_roi = y_orig+(box_dim*(ro))+(window*int(math.ceil(ro/2)))+(wall*(int(math.ceil((ro+1)/2))-1))
x_roi = x_orig+(box_dim*(col))+(wall*col)
Behavior = row['mean']
starting_frame = row['first']
ending_frame = row['last']
length = row['len']
os.chdir("C:\****")
cap = cv2.VideoCapture("BN4 A4-F4, H4.avi")
#Code for what I do with the videos, not relevant to the question
cap.release()
cv2.destroyAllWindows()
df4.apply(apply_each_behavior, axis=1)
except:
continue
I have a program that analyzes fish behavior and categorizes it, giving each behavior a number between 1-80. Then, my code groups the frames in which their behaviors took place for at least 50 seconds. I end up with a csv file that looks like this. Note that mean = Behavior:
Example of behaviors analyzed in Fish 1_1:
behavior | first | last | len |
---|---|---|---|
0 | 7 | 32 | 87 |
1 | 19 | 277 | 333 |
2 | 1 | 785 | 940 |
3 | 30 | 4062 | 4125 |
4 | 29 | 4214 | 4269 |
5 | 7 | 4450 | 4599 |
6 | 1 | 4612 | 4775 |
7 | 7 | 4778 | 4882 |
8 | 8 | 4945 | 4999 |
My code is meant to focus on a specific fish and crop the video frames from the first frame of a specific behavior until the last frame of the behavior, then do the same for the next behavior of that fish in a loop.
For some reason, my code only crops frames with the last behavior of fish 8_10, which is the last fish. Lately, I have added the for loops and the try/except.
Why is this starting at fish 8_10 instead of fish 1_1?
Thanks!
import os
import pandas as pd
import cv2
import math
#####Generating avi files with roi being specific fish, for frame ranges where behaviors are consistent for at least 1 second or 50 frames
for ro in range(8): # iterate through the rows, 8 rows total
for col in range(10): # interate through the columns, 10 columns total
try:
# Starting and ending frames, length of video in frames
os.chdir("C:\****\BN4 A4-F4, H4\%d_%d" % (ro+1, col+1))
df4 = pd.read_csv("BN4 A4-F4, H4_row%d_column%d Behaviors.csv" % (ro+1,col+1), names=['mean','first', 'last', 'len'], skiprows=2)
except:
continue
def apply_each_behavior(row):
# Dimension for cropping out each fish
box_dim = 220
# Set parameters for locating each ZeChat unit as ROIs for cropping
y_orig = 25
x_orig = 20
wall = 20
window = 15
# locate the roi so that each cell can be selected by just changing the row and column number:
y_roi = y_orig+(box_dim*(ro))+(window*int(math.ceil(ro/2)))+(wall*(int(math.ceil((ro+1)/2))-1))
x_roi = x_orig+(box_dim*(col))+(wall*col)
# Identifies the value in each row and column as the function is applied
Behavior = row['mean']
starting_frame = row['first']
ending_frame = row['last']
length = row['len']
os.chdir("C:\****")
cap = cv2.VideoCapture("BN4 A4-F4, H4.avi")
#****** Code for what I do with the videos, not relevant to the question*****
cap.release()
cv2.destroyAllWindows()
df4.apply(apply_each_behavior, axis=1)
Here is an example of some of the output:
Opening BN4 A4-F4, H4.avi
Opening video BN4 A4-F4, H4.avi
Frame Rate : 50 frames per second
Frame count : 46728.0
....
Writing video for Behavior 32, fish 8_10, frames 1856-1969, length 114, BN4 A4-F4 H4.avi
The following numbers should be identical:
counter: 114 frames
length: 114 frames
0 None
1 None
2 None
3 None
dtype: object
I figured it out. The issues was in where I had the except. I was essentially telling it to iterate through the list, and at the end of the list then run the function. Here is the fixed code:
for ro in range(8): # iterate through the rows, 8 rows total
for col in range(10): # interate through the columns, 10 columns total
try:
# Opening the behavior files if they are found, 2_9 and 5_10 do not have an original data file, so they do not have a behavior file
os.chdir("C:\****\BN4 A4-F4, H4\%d_%d" % (ro+1, col+1))
df4 = pd.read_csv("BN4 A4-F4, H4_row%d_column%d Behaviors.csv" % (ro+1,col+1), names=['mean','first', 'last', 'len'], skiprows=2)
def apply_each_behavior(row):
# Dimension for cropping out each fish
box_dim = 220
# Set parameters for locating each ZeChat unit as ROIs for cropping
y_orig = 25
x_orig = 20
wall = 20
window = 15
# locate the roi so that each cell can be selected by just changing the row and column number:
y_roi = y_orig+(box_dim*(ro))+(window*int(math.ceil(ro/2)))+(wall*(int(math.ceil((ro+1)/2))-1))
x_roi = x_orig+(box_dim*(col))+(wall*col)
Behavior = row['mean']
starting_frame = row['first']
ending_frame = row['last']
length = row['len']
os.chdir("C:\****")
cap = cv2.VideoCapture("BN4 A4-F4, H4.avi")
#Code for what I do with the videos, not relevant to the question
cap.release()
cv2.destroyAllWindows()
df4.apply(apply_each_behavior, axis=1)
except:
continue