I can cut the video based on seconds, for example, I can cut the video from second 0 to second 10 and from second 10 to second 20. But I need to cut the video from frame 0 to frame 250 and from frame 250 to frame 500 because of some error due the counting of second. Does anyone has any idea about this?
Here is the code I use to cut based on seconds:
required_video_file = "H8.avi"
with open("Z:/temp/LetÃcia/Videos/teste/times.txt") as f:
times = f.readlines()
times = [x.strip() for x in times]
for time in times:
starttime = int(time.split('-')[0])
endtime = int(time.split("-")[1])
ffmpeg_extract_subclip(required_video_file, starttime, endtime, targetname=str(times.index(time)+1)+".avi")
I want to make an 1 hour - long gif which will consist of 60 frames.
I already have built a gif_making function using PIL:
sortedFiles = sorted(glob.glob('*.png'),key=os.path.getmtime)
sortedFilesBackwards = sorted(glob.glob('*.png'),key=os.path.getmtime, reverse= True)
full = [] + sortedFiles[:-1] + sortedFilesBackwards[:-1]
frames = [Image.open(image) for image in full]
frame_one = frames[0]
frame_one.save(f"{units}{fileName}.gif", format="GIF", append_images=frames,
save_all=True, duration=12000, loop=0)
However, when I set the duration = 360 000 (milliseconds = 1 hour), I receive the following error:
struct.error: ushort format requires 0 <= number <= (32767 *2 +1)
I work on macOS.
P.S : I think it has something to do with the maximum amount of data within a struct ?
The duration is how long to display each frame for in milliseconds, so you need to set it to 1,000 for each frame to be displayed for a second.
Or set it to 30,000 for each frame to be displayed for 30 seconds and double up your frames.
Set FPS value when you saving your GIF
For example:
ani.save('animation.gif', fps=3)
The value you set will lengthen or shorten your gif
I'm trying to read frames from a certain timestamp to a certain timestamp, problem is that just after setting it up to start at 800 milliseconds for example:
start_time = 0.8
end_time = 4
MILLISECONDS = 1000
cap.set(cv2.CAP_PROP_POS_MSEC, float(start_time * MILLISECONDS))
Now I try and check where it is with:
cap.get(cv2.CAP_PROP_POS_MSEC)
Which returns:
13346.680013346679
and according to OpenCV docs, that flag stands for
Current position of the video file in milliseconds.
Which is kind of confusing because my entire video is 4 seconds long i.e. 4000 milliseconds, the entire code snippet is:
def load_video(path, start_time, end_time, skip_frames=False):
MILLISECONDS = 1000
frame_pos = 0
cap = cv2.VideoCapture(path)
cap.set(cv2.CAP_PROP_POS_MSEC, float(start_time * MILLISECONDS))
frames = []
try:
while cap.isOpened() and cap.get(cv2.CAP_PROP_POS_MSEC) <= float(end_time * MILLISECONDS):
ret, frame = cap.read()
if not ret:
break
# OpenCV default capturing is on BGR format,
# if RGB is needed then un-comment this line:
# frame = frame[:, :, [2, 1, 0]]
frames.append(frame)
if skip_frames:
# If we want to take every 5th frame (where there is a an action documented).
frame_pos += 12
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_pos)
finally:
cap.release()
return np.array(frames)
The point is to read from a certain timestamp to a certain timestamp, but the 2nd condition in the while statement obviously isn't satisfied since 13346.680013346679 > 4000 from the get go, and most strangely ret, frame = cap.read() actually reads a frame when I'm executing it in the debugger just before stepping to the while check.
So what I'm doing wrong here?
P.S
The video file is .avi & 60fps.
I have been looking for a couple days now and cannot find an answer. I am creating a worksheet with python and is using the openpyxl module. I am able to format cells and insert values in the cells. I can insert images in cells, but i need to align the images.
align = Alignment(horizontal = 'left', vertical = 'center', wrap_text = True
IMAGECELL = ws.cell['A1']
IMAGECELL.alignment = align
This is my code for aligning text. It is not working with images.
I know my solution is not perfect but it worked for me, just want to help others save time. I wanted to add multiple images too and align them but when I tried adding images they were placed on top of each other. It turned out that you have to use anchors in openpyxl to position images. and I wanted to put them in 2 x 3 Grid. Here's my solution.
def excel_writer(self, _location=None, images=None):
if images is None or len(images) == 0:
return
for image in images:
proto_image = Image(str(image))
# A bit resizing
proto_image.height = 250
proto_image.width = 300
if count == 0:
proto_image.anchor = 'A3'
if count == 1:
proto_image.anchor = 'F3'
if count == 2:
proto_image.anchor = 'L3'
if count == 3:
proto_image.anchor = 'A20'
if count == 4:
proto_image.anchor = 'F20'
if count == 5:
proto_image.anchor = 'L20'
if count == 6:
proto_image.anchor = 'A43'
sheet.add_image(proto_image, proto_image.anchor)
count += 1
workbook.save(_location)
So, I am going through a list of images and adding them on sheet at anchors position. For first image, the count is 0 and the anchor is A3; Which means 1st column, 3rd row. For 2nd image, same 3rd row but different column and so on.
One thing to notice is that I have calculated the space between columns manually. If your image is greater in width, you'll need to further move it along +ve x-axis like from column A to L.
My aim is to create a grid that looks like the following http://i49.tinypic.com/f39hxv.png, where each number represents the number of 'preperation flakes' found in each square (see data snippet below)
The code so far is as follows:
import csv
import os
import pygame
# the functions for display
def disp(phrase,loc,screen): # function to display phrase at loc on surface.
s = font.render(phrase, True, (255,255,255))
screen.blit(s, loc) #
def text_display_csv(filename,surface):
'''Display .csv file contents on surface'''
f = csv.reader(open("Flint catalogue v1.7 4 Feb 13 2013.csv")) # open the csv file in one line!
for row in f:
y = f.line_num # assign y as Row no.
for x,item in enumerate(row): # Get column number(x) and item
disp(item, (64*x+10,64*y+10), surface) # display item
pygame.init()
pygame.font.init()
font = pygame.font.SysFont("Courier",10) # font initialisation
screen = pygame.display.set_mode((1200,1200))
filename = 'the .csv file'
text_display_csv(filename,screen) # text is displayed
pygame.display.update() # screen updated
# Main loop, does nothing! :)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
break
if not running:
break
I would like the grid to look a bit like this (but my trouble is putting data from the database into this array):
import csv
import os
import pygame
# Define some colors
black = ( 0, 0, 0)
white = ( 255, 255, 255)
green = ( 0, 255, 0)
red = ( 255, 0, 0)
# This sets the width and height of each grid location
width=20
height=20
# This sets the margin between each cell
margin=5
# Create a 2 dimensional array. A two dimesional
# array is simply a list of lists.
grid=[]
for row in range(10):
# Add an empty array that will hold each cell
# in this row
grid.append([])
for column in range(10):
grid[row].append(0) # Append a cell
# Set row 1, cell 5 to one. (Remember rows and
# column numbers start at zero.)
grid[1][5] = 1
grid[1][6] = 2
# Initialize pygame
pygame.init()
# Set the height and width of the screen
size=[255,255]
screen=pygame.display.set_mode(size)
# -------- Main Program Loop -----------
while done==False:
# Set the screen background
screen.fill(black)
# Draw the grid
for row in range(10):
for column in range(10):
color = white
if row[4]in c == 1:
color = green
pygame.draw.rect(screen,color,[(margin+width)*column+margin, (margin+height)*row+margin,width,height])
# Limit to 20 frames per second
clock.tick(20)
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
pygame.quit()
The data is a s follows:
http://tinypic.com/view.php?pic=2rdgn02&s=6
So to sum up. i would like different 'classifications' (see data) to be displayed in the grid like the pic at the start.
Thanks for the help
Tom
Here's some code,
That is your code other than 10 chars max (except comments and removals), but causes Big changes.
import pygame,csv
def disp(phrase,loc,screen):
s = font.render(phrase, True, (255,255,255))
screen.blit(s, loc)
# not needed
def text_display_csv(filename,surface):
'''Display .csv file contents on surface'''
f = csv.reader(open(filename))
for row in f:
y = f.line_num
for x,item in enumerate(row):
disp(item, (60*x+10,12*y-2), surface) # changed y distance
pygame.init()
pygame.font.init()
font = pygame.font.SysFont("Courier",10) # Changed font size
screen = pygame.display.set_mode((640,480)) # changed window size
filename = "Flint catalogue v1.7 4 Feb 13 2013.csv"
text_display_csv(filename,screen)
pygame.display.update()
# Main loop, does nothing! :)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
break
if not running:
break
Update 1
Ok, I see.
So, you want to display data in P at Grid no S...
Here's the code for that too. Just change text_display_csv to this,
def text_display_csv(filename,surface):
'''Display .csv file contents on surface, after processing'''
f = csv.reader(open(filename))
# The Processing
data = {}
for row in f:
y = f.line_num
if len(row) >= 19:
# See if S contains a number,
# if No: Print the msg
# else: add to dict, in form of S:P
try:
val = int(row[18]) # S is the 19th column
except ValueError:
print "Skipped row no",y,"as column S doesn't contain number"
continue
else: # if a number, add to the dict
data[val] = row[15] # P is the 16th column
print "File Loaded"
# the display part
width = 6
for loc in data:
item = data[loc] # get item (string to display)
y = loc//width # column
x = loc % width # row
disp(item, (60*x +10,30*y +10), surface)
What's Happening here:
Load .csv
If a row has items till at least S column,
If value at S is a number, get it's integer value.
Then add information to a dictionary in the form of S : P, Where
S is the integer
P the string/value at column P.
Otherwise print a msg, and move on to the next row(if any)
Display Data at their respective places.
Now the only problem is that the numbers have to start with zero.
To overcome that, Just add
loc += 1
Before
y = loc//width
Your grid lines can be drawn using pygame.draw.line, you can figure that out.