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
Asked By: Chris

||

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
Answered By: Chris
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.