Jump to content

Here have fun with some malfunctioning python code

Justapersononthenet
Go to solution Solved by Sauron,
17 minutes ago, Justapersononthenet said:

I don't have time to learn how cv works

Before you learn opencv maybe you should focus on the basics of programming...?

 

All those "if" statements could be written as 3 lines

if text[i] == " ":
	text[i] = "space"
video.write(cv2.imread(os.path.join(image_folder, text[i])))

as for why your code isn't working, have you made sure there actually are images named from "a" to "z" without extension in the folder you're running the script in?

 

Also you aren't creating any windows so why are you trying to destroy some?

cv2.destroyAllWindows()

 

import cv2
import os

text = list(input("input text"))
image_folder = (r"C:\Users\Edoardo\Desktop\mouth_animation")
video_name = 'output.avi'


images = [img for img in os.listdir(image_folder) if img.endswith(".png")]
frame = cv2.imread(os.path.join(image_folder, images[0]))
height, width, layers = frame.shape

video = cv2.VideoWriter(video_name, 0, 1, (width,height))

for i in range(len(text)):
    if text[i] == " ":
        video.write(cv2.imread(os.path.join(image_folder, "space")))
    if text[i] == "a":
        video.write(cv2.imread(os.path.join(image_folder, "a")))
    if text[i] == "b":
        video.write(cv2.imread(os.path.join(image_folder, "b")))
    if text[i] == "c":
        video.write(cv2.imread(os.path.join(image_folder, "c")))
    if text[i] == "d":
        video.write(cv2.imread(os.path.join(image_folder, "d")))
    if text[i] == "e":
        video.write(cv2.imread(os.path.join(image_folder, "e")))
    if text[i] == "f":
        video.write(cv2.imread(os.path.join(image_folder, "f")))
    if text[i] == "g":
        video.write(cv2.imread(os.path.join(image_folder, "g")))
    if text[i] == "h":
        video.write(cv2.imread(os.path.join(image_folder, "h")))
    if text[i] == "i":
        video.write(cv2.imread(os.path.join(image_folder, "i")))
    if text[i] == "m":
        video.write(cv2.imread(os.path.join(image_folder, "m")))
    if text[i] == "n":
        video.write(cv2.imread(os.path.join(image_folder, "n")))
    if text[i] == "o":
        video.write(cv2.imread(os.path.join(image_folder, "o")))
    if text[i] == "p":
        video.write(cv2.imread(os.path.join(image_folder, "p")))
    if text[i] == "q":
        video.write(cv2.imread(os.path.join(image_folder, "q")))
    if text[i] == "r":
        video.write(cv2.imread(os.path.join(image_folder, "r")))
    if text[i] == "s":
        video.write(cv2.imread(os.path.join(image_folder, "s")))
    if text[i] == "t":
        video.write(cv2.imread(os.path.join(image_folder, "t")))
    if text[i] == "u":
        video.write(cv2.imread(os.path.join(image_folder, "u")))
    if text[i] == "v":
        video.write(cv2.imread(os.path.join(image_folder, "v")))
    if text[i] == "w":
        video.write(cv2.imread(os.path.join(image_folder, "w")))
    if text[i] == "x":
        video.write(cv2.imread(os.path.join(image_folder, "x")))
    if text[i] == "y":
        video.write(cv2.imread(os.path.join(image_folder, "y")))
    if text[i] == "z":
        video.write(cv2.imread(os.path.join(image_folder, "z")))

cv2.destroyAllWindows()
video.release()

sooooo this should be a lipsync, for 2d animations, it takes the mouth expressions saved as images in a folder and converts them to roughfly fit the text, ouputting a video, atm the output is a 6kb (probably empy) corrupted .avi file, I got the "image to video" code from here, since I don't have time to learn how cv works

Link to comment
Share on other sites

Link to post
Share on other sites

You're running a bunch of:

if (text == x)

    do something with x

-lines

 

wouldn't it be much easier to:

1. check if the piece of text is a letter of the alphabet or whitespace

2. if it's a whitespace, do "space"

3. otherwise do something with the letter

 

Something like this in pseudo(-ish)code:

for each(character in text)
{
	string characterToWrite = "";
    
	if(character == " ")
    {
    	characterToWrite = "space";
    }
    else if(character == FromTheAlphabet)
    {
    	characterToWrite = character;
    }
    else
    {
    	// Not valid/implemented character, handle however you must.
    }
    
    video.write....(characterToWrite);
}

Would make the code significantly smaller and easier to read.

 

But I don't know python exactly. What part of the code is failing? What is making the file corrupt?

"We're all in this together, might as well be friends" Tom, Toonami.

 

mini eLiXiVy: my open source 65% mechanical PCB, a build log, PCB anatomy and discussing open source licenses: https://linustechtips.com/topic/1366493-elixivy-a-65-mechanical-keyboard-build-log-pcb-anatomy-and-how-i-open-sourced-this-project/

 

mini_cardboard: a 4% keyboard build log and how keyboards workhttps://linustechtips.com/topic/1328547-mini_cardboard-a-4-keyboard-build-log-and-how-keyboards-work/

Link to comment
Share on other sites

Link to post
Share on other sites

17 minutes ago, Justapersononthenet said:

I don't have time to learn how cv works

Before you learn opencv maybe you should focus on the basics of programming...?

 

All those "if" statements could be written as 3 lines

if text[i] == " ":
	text[i] = "space"
video.write(cv2.imread(os.path.join(image_folder, text[i])))

as for why your code isn't working, have you made sure there actually are images named from "a" to "z" without extension in the folder you're running the script in?

 

Also you aren't creating any windows so why are you trying to destroy some?

cv2.destroyAllWindows()

 

Don't ask to ask, just ask... please 🤨

sudo chmod -R 000 /*

Link to comment
Share on other sites

Link to post
Share on other sites

1 minute ago, Sauron said:

 

 

Also you aren't creating any windows so why are you trying to destroy some?

 

don't have to ask me but rather the guy that i got this from...Would happily learn opencv but don't have time rn, as for the if statements I've already got that, no need to be pretty and efficent for the moment, would like to not use the same image that is used for more than one character so I can't name them by the characters they express if we really want to simplify the process.

 

8 minutes ago, Sauron said:

as for why your code isn't working, have you made sure there actually are images named from "a" to "z" without extension in the folder you're running the script in?

 

well that works...what's up with the extension? guess I'll not discover that today...

 

thank you!

Link to comment
Share on other sites

Link to post
Share on other sites

11 minutes ago, Justapersononthenet said:

don't have to ask me but rather the guy that i got this from...

I'm assuming it's a residue from his source http://tsaith.github.io/combine-images-into-a-video-with-python-3-and-opencv-3.html

13 minutes ago, Justapersononthenet said:

no need to be pretty and efficent for the moment

It's not a matter of efficiency, it's a matter of preserving your sanity. What if you had 1000 different images?

14 minutes ago, Justapersononthenet said:

would like to not use the same image that is used for more than one character

There are solutions for that that don't involve manually writing an if statement.

14 minutes ago, Justapersononthenet said:

well that works...what's up with the extension? guess I'll not discover that today...

It's quite simple, you're looking for a file that's called "a" but the file was actually called "a.png" so opencv couldn't find it. If you want to use the extensions just append ".png" at the end of the string.

Don't ask to ask, just ask... please 🤨

sudo chmod -R 000 /*

Link to comment
Share on other sites

Link to post
Share on other sites

1 minute ago, Sauron said:

It's quite simple, you're looking for a file that's called "a" but the file was actually called "a.png" so opencv couldn't find it. If you want to use the extensions just append ".png" at the end of the string.

*also me* tries to remove a .py extension an put it into the program as an "image",

I'm self learning python and It has some things that just didn't and/or don't make sense to me, I got that it was the simplest programming language a few moments after working with an arduino and swearing because of : that I dodn't write at the end of lines, random uppercases in command names and no suggestion box(the box that pops-up with the possible command that you are writing and let's, autocomplete it and gives some clue about the function of the command).

 

 

whatever

Image result for improvise adapt overcome

Link to comment
Share on other sites

Link to post
Share on other sites

My suggestion would be to simplify your code and generate Y4M files (uncompressed video) from your pictures. Then it's simply an issue of concatenating y4m videos into single files.

 

Y4M files are super simple, a header followed by frames (with their own tiny header).. see : https://wiki.multimedia.cx/index.php/YUV4MPEG2

 

So a header could look like this:

320 x 240 pixels , 30 fps (30/1) , progressive (no interlacing) , aspect ratio 1:1, YCbCr 4:4:4 (3 bytes per pixel)

 

YUV4MPEG2<space>W320<space>H240<space>F30:1<space>Ip<space>A1:1<space>C444<newline 0x0A>

frames (one after another)

FRAME<newline 0x0A>
[Y bytes for the frame][Cb bytes for the frame][Cr bytes for the frame]

 

So you could have a Y4M file for "A", a Y4M file for B and so on ... you just have to make your program read the header (read bytes until you encounter  0x0A and extract from that the width and height or you can just use your predefined width and height if they're all gonna be the same)

then repeat 

  read until you get 0x0A ( FRAME header)

  read n bytes , for the most common YCbCr 4:2:0 you have [(height X width) / 4 ] bytes

 

If you have a series of pictures for each letter, number them incrementally ex picture001.bmp , picture002.bmp

Load the first picture in Virtualdub and it will auto load the rest

Select Video > Compression : choose no compression

Select Video > Frame rate..  : set your fps

Select Video > Color depth ...  output format 4:4:4 planar YCbCr YV24   or 4:2:0 YCbCr YV12

and save video as avi

 

then go in ffmpeg and run  

 

ffmpeg  -i c:/path/to/input.avi  c:/path/to/output.y4m

 

That's your A.Y4M, B.Y4M , etc etc  when you want to append one to your movie, you just skip the header, then copy the frames from the file to your video.

 

So you can combine multiple in a single y4m file by writing the header a single time and just concatenating the frames and when you're done you can encode the Y4M file in a compressed format.

A lot of video programs will open a y4m file.

If you want to do it command line :

 

x264.exe --preset slower --crf 20 -o c:/path/to/output.[264|mkv]  c:/path/to/input.y4m

 

 

You could also load ALL your pictures in Virtualdub as a sequence, export to avi , then convert to y4m with ffmpeg  and then you have a big y4m file with all your frames.

Then make a simple json or something with the definitions ... video for letter "A" starts from frame 10 and goes on for 15 frames,  video for letter 'B" starts at frame 26 and goes on for 20 frames ... and so on.

 

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×