├── LICENSE ├── README.md ├── ReadMe_Deforum_Licensing.txt ├── Version_0.7.6 ├── Deforum_version │ ├── Named_Pipes_version_of_deforum │ │ └── deforum-for-automatic1111-webui.zip │ └── Websockets_version_of_deforum │ │ └── deforum-for-automatic1111-webui.zip ├── ReadMe_Deforum_Licensing.txt ├── ReadMe_Installation_and_running_Deforumation.txt └── deforumation │ ├── Deforumation_start_named_pipes.bat │ ├── Deforumation_start_websockets.bat │ ├── Dirty_Fix_To_Fix_Freeze_Problem_old_and_probably_obsolete │ ├── autoencoder.py │ └── deforumation_quick_fix.txt │ ├── LICENSE │ ├── README.md │ ├── colab_files │ ├── animation.py │ ├── deforum_mediator.py │ └── render.py │ ├── deforum-for-automatic1111-webui │ └── scripts │ │ └── deforum_helpers │ │ ├── animation.py │ │ ├── deforum_mediator.py │ │ ├── deforum_mediator_named_pipes │ │ └── deforum_mediator.py │ │ └── render.py │ ├── deforum_settings_keys.txt │ ├── deforumation.py │ ├── deforumation_settings_motions.txt │ ├── deforumation_ws.py │ ├── images │ ├── arm_off.bmp │ ├── arm_on.bmp │ ├── down_arrow.bmp │ ├── forward_closest.bmp │ ├── left_arrow.bmp │ ├── lock_off.bmp │ ├── lock_on.bmp │ ├── look_down.bmp │ ├── look_left.bmp │ ├── look_right.bmp │ ├── look_upp.bmp │ ├── parseq_off.bmp │ ├── parseq_on.bmp │ ├── play.bmp │ ├── record_off.bmp │ ├── record_on.bmp │ ├── record_recording.bmp │ ├── reverse_fov_off.bmp │ ├── reverse_fov_on.bmp │ ├── rewind_closest.bmp │ ├── right_arrow.bmp │ ├── rotate_left.bmp │ ├── rotate_right.bmp │ ├── stop.bmp │ ├── upp_arrow.bmp │ ├── zero.bmp │ └── zero_active.bmp │ ├── mediator.py │ ├── mediator_ws.py │ ├── motion_images │ ├── Far_Zoom_In_(30 FPS).gif │ ├── Far_Zoom_Out_(30 FPS).gif │ ├── close_rotation_left.gif │ ├── close_rotation_right.gif │ ├── far_rotation_left.gif │ ├── far_rotation_right.gif │ ├── medium_rotation_left.gif │ └── medium_rotation_right.gif │ ├── requirements.txt │ └── run_me_first_install_requirements.bat └── github_images ├── Aiwakening.png ├── DM.png ├── DMQT.png ├── DMQTyou.png ├── Deforumation_Tutorial.png ├── Linol_1.PNG ├── Live_preview.png ├── aixite.png ├── arm_off.bmp ├── arm_on.bmp ├── controlnet.png ├── current_version.png ├── current_version_gentle_zero_rotation.png ├── deforumation_design_01.jpg ├── install.PNG ├── newinterface4.png ├── newinterface5.png ├── output.gif ├── panning.PNG ├── patreon.png ├── replay.png ├── resume.PNG ├── rewindforward.PNG ├── rotation.PNG ├── smile.gif ├── strengthCFG.PNG ├── tilt.PNG └── zero.bmp /README.md: -------------------------------------------------------------------------------- 1 | `Deforumation 0.7.6 No more updates will be done to this repo. Se new repo for DeforumationQT Version 0.1.5 2 | https://github.com/Rakile/DeforumationQT 3 | =============================================== 4 | 5 | ![img](github_images/DM.png) 6 | 7 | =============================================== 8 | 9 | 10 | 11 | 12 | 13 | 14 | Installation instructions for Deforumation 0.7.6 are below, and there's also a 'how-to' file in the zip: loc deforumation\Version_0.7.6\ReadMe_Installation_and_running_Deforumation.txt 15 | 16 | Stuck or puzzled? Reach out to us! 17 | 18 | Join our Discord https://discord.gg/UZvrg7ph9k 19 | =============================================== 20 | LAInol: [YouTube Channel](https://www.youtube.com/@lainolkar) 21 | ------------- 22 | New Feature Alert: Voice Commands in Deforumation! 23 | 24 | Deforumation now listens to your voice! Here's how you can command it: 25 | 26 | Push to record. Then, use these magic words to control Deforumation: 27 | : Speaks your sentence into the second prompt window. 28 | add + : Adds your spoken words to the current sentence. 29 | cancel: Utter this to halt the prompt output entirely. 30 | Pan left, pan right, pan up, pan down: Pans around using preset values. 31 | Zoom in, zoom out: Zooms in or out. Say, "Zoom in 20" to zoom in by 0.20. 32 | Rotate left, rotate right, rotate up, rotate down: Controls rotation with preset values. 33 | Tilt left, Tilt right: Adjusts the tilt. 34 | Reset panning/zoom/rotation/tilt: Resets the respective values to default. 35 | Embrace the power of your voice with Deforumation!" 36 | Ralika / LAInol 37 | 38 | Here's to making Deforumation even more delightful (and less 'old school')!" 39 | 40 | `DISCLAIMER!!!` 41 | =============================================== 42 | `!!!THERE WILL BE NO DEFORUM SUPPORT IF YOU USE THIS EXTENSION!!!` 43 | =============================================== 44 | --------------------------------------------------------------------------------------------------------------------------------------- 45 | 46 | Deforumation: Unofficial Extension for Deforum 47 | =============================================== 48 | 49 | **IMPORTANT: No official Deforum support will be provided if you use this extension.** 50 | 51 | 52 | 53 | Table of Contents 54 | ----------------- 55 | 1. [Introduction](#introduction) 56 | 2. [Prerequisites](#prerequisites) 57 | 3. [Key Features](#key-features) 58 | 4. [Installation Guide](#installation-guide) 59 | 5. [Installation Tutorial](#installation-Tutorial) 60 | 6. [Compatibility](#compatibility) 61 | 7. [Usage and Tips](#usage-and-tips) 62 | 8. [Disclaimer](#disclaimer) 63 | 9. [Discord Channel](#Discord-Channel) 64 | 10. [Ongoing Work](#Ongoing-Work) 65 | 11. [in-depth information](#in-depth-information) 66 | 12. [patreon](#patreon) 67 | 68 | 69 | 70 | 71 | Support our work via Patreon or buymeacoffee 72 | =============================================== 73 | [Deforumation Patreon](https://www.patreon.com/Deforumation) 74 | ------------ 75 | [buymeacoffee.com](https://www.buymeacoffee.com/deforumation) 76 | ------------ 77 | Deforumation is a free tool for everyone to use. We appreciate all and any donations/support to keep Deforumation up to date and adding new features together with the community. 78 | 79 | 80 | 81 | 82 | Latest version / features 83 | ----------------- 84 | [Latest version](#Latest-version) (2023-06-18) 85 | 86 | 87 | Introduction 88 | ------------ 89 | Deforumation is an unofficial extension for Deforum that provides a Graphical User Interface (GUI) to remotely control Deforum 3D motions, zoom and angle , strength value (toggle to use deforum strenght schedule), CFG Scale, sampler steps, seed, cadense scale, noise values, parameters for use up to five controlnets, and prompts in real-time. It also offers pausing, rewinding, forwarding, and resuming by setting current image to fix any undesired outcomes during the rendering process. 90 | 91 | Recently added features are checkboxes for enable / disable fuctions from Deforumation. Checkboxes are added to Prompt, Strenght value, CFG scale, Cadense scale, Noise values, camera panning and camera rotation. This makes it possible to apply sceduling to any of those values from Deforum or from Parseq. 92 | Also added customizable curves for use with armed motions controls. Parameters for up to five controlnets. Cadence Re-Scheduler, this is a module to recalculate the 93 | Cadence Schedule due to "tween" pictures not reacting to schedueled values. 94 | 95 | Key Features 96 | ------------ 97 | - Live View (separate window) of the rendered pictures. 98 | - Separate prompting input boxes with prioritising possibility 99 | - Controlling movements while rendering, now with armed movements and presetted curves 100 | - Live manipulation of key values that effects the animation 101 | - Live manipulation of controlnets 102 | - Pause, rewind, and redo functions 103 | - Ability to import parseq json files to use as guide 104 | - Two different communication protocols, websockets and named pipes. This is due to problem with freezing renders. 105 | 106 | Prerequisites 107 | ------------ 108 | 1. Local instance of SD ([AUTOMATIC1111/stable-diffusion-webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui)) 109 | 2. Installed Deforum Extension for AUTOMATIC1111 ([deforum-art/deforum-for-automatic1111-webui](https://github.com/deforum-art/deforum-for-automatic1111-webui)) 110 | 111 | Installation Guide 112 | ------------------- 113 | 1. **Clone or download** the git repository `git clone https://github.com/Rakile/deforumation` (https://github.com/Rakile/deforumation) and unpack the zip file. Keep deforumation folder outside your `"stable-diffusion-webui"` path. 114 | 2. **Replace files** (render.py, animation.py, deforum_mediator.py) in the Automatic1111 path ".\extensions\deforum-for-automatic1111-webui\scripts\deforum_helpers\" with the downloaded files from Deforumation. To use the "named pipes" protocol the `"mediator".py` file must be copied from the `"deforum_mediator_named_pipes"` folder to your `"\\stable-diffusion-webui-02\extensions\deforum-for-automatic1111-webui\scripts\deforum_helpers"` 115 | 3. **Install dependencies** by running `python -m pip install -r requirements.txt` or using the `"run_me_first_install_requirements.bat"` file. 116 | 4. **!!IMPORTANT!!** Check that you have installed websocket version 10.4.(the correct version is included in the reqirements.txt) Do this by running the command: python -m websockets --version 117 | in a CMD (command line window) window. People have noticed that python websocket library, with a version higher or equal to 11.0, makes Deforum and Deforumation freeze. 118 | See (https://github.com/Rakile/deforumation/blob/main/Dirty_Fix_To_Fix_Freeze_Problem/deforumation_quick_fix.txt) for more information. 119 | 5. To start Deforumation using websocket protocol **Run the Mediator** (mediator.py) `H:\named\deforumation>python mediator.py` and the **Deforumation GUI** (deforumation.py) `H:\named\deforumation>python deforumation.py` in CMD inside deforumation path. Or use the `"Deforumation_start_websockets.bat"` file. 120 | 6. To start Deforumation using named pipes protocol **Run the Mediator** (mediator.py) `H:\named\deforumation>python mediator.py pipes` and the **Deforumation GUI** (deforumation.py) `H:\named\deforumation>python deforumation.py pipes` in CMD inside deforumation path. Or use the `"Deforumation_start_named_pipes.bat"` file. 121 | 7. To use the `"named pipes"` protocol the correct `"mediator".py` file must be copied from the `"deforum_mediator_named_pipes"` folder to your `"\\stable-diffusion-webui-02\extensions\deforum-for-automatic1111-webui\scripts\deforum_helpers"` 122 | 8. **Set to 3D in keyframes TAB** In the Deforum extention in the `Keyframes TAB, you have to choose "3D"`, else it will not work. 123 | 124 | Installation Tutorial 125 | ------------- 126 | [Installation Tutorial](https://youtu.be/7KmtmPlhzNs) (Tutorial is for websocket protocol, follow the above installation guide to use named pipes protocol) 127 | 128 | Compatibility 129 | ------------- 130 | Deforumation may not be compatible with all versions of Deforum. For now Deforum does not have the communication module in there core files. 131 | For now we try to update Deforumation as Deforum is updated. 132 | 133 | Usage and Tips 134 | -------------- 135 | Deforumation is a valuable tool for understanding how different parameters affect the image generation process. However, it is essential to remember that using Deforumation may result in some issues, as it is not an officially supported extension. 136 | 137 | 138 | - In the Deforum extention in the Keyframes TAB, you have to choose "3D", else it will not work. Before pushing "Generate" in the deforum extention, prime the communication by inserting a Positive and a Negative prompt in the Deforumation GUI. 139 | - Be sure that your Deforum extension does work berfore installing Deforumation. 140 | - Make sure the Mediator is running to ensure proper communication between Deforum and Deforumation. 141 | - Experiment with different settings to find the most effective values for your specific project. 142 | - Change "live preview" settings in automatic1111 to draft for faster rendering. 143 | - Check the "LIVE RENDER" box in deforumation to se generated frames. 144 | 145 | 146 | Disclaimer 147 | ---------- 148 | By using Deforumation, you understand and acknowledge that it is an unofficial, third-party extension for Deforum. There will be no official support provided for Deforum when using this extension. Use it at your own risk. 149 | 150 | 151 | 152 | Discord Channel 153 | ---------- 154 | 155 | [Welcome To Deforumation] (https://discord.gg/rbKFVh9v87) 156 | 157 | 158 | 159 | 160 | Latest version 161 | ---------- 162 |
163 | Latest Version Info 164 | 165 | 2023-05-15 166 | Lots of added stuff 167 | - Gentle Zero can now go from any motion to any other motion in panning and rotation values 168 | - ControlNet in Deforum, can now be controlled by Deforumation 169 | - Live Render can now replay a range of images (no stitching), to get a fast view of how the animation is going to look 170 | 171 | 172 |
173 | 174 |
175 | Latest Version Info 176 | 177 | 2023-05-03 (later in the evening) 178 | 179 | - Introducing another "Gentle Zero" for rotation. It works separate from "Gentle Zero" for panning. 180 | 181 | ![img](github_images/current_version_gentle_zero_rotation.png) 182 | 183 | 184 |
185 | 186 |
187 | Latest Version Info 188 | 189 | 2023-05-03 190 | 191 | - Separate prompting input boxes with prioritising possibility 192 | 193 | - All prompts can now be minimized, making the window smaller, 194 | and maybe some people will find this easier to work with. 195 | 196 | ![img](github_images/current_version.png) 197 | 198 | 199 |
200 | 201 | 202 | In-depth information 203 | ---------- 204 | 205 | 206 |
207 | How it works 208 | ## How it works 209 | Watch this video to get a feeling of how to use Deforumation... or read on below. 210 | [![Watch the video](github_images/Deforumation_Tutorial.png)](https://www.youtube.com/watch?v=v1h2jo3f5U4) 211 | 212 | ## Recommended setting 213 | 214 | In settings, Live previews recommends this setting. This gives you better visual feedback. 215 | 216 | ![img](github_images/Live_preview.png) 217 | 218 | 219 | In the Deforum extention in the Keyframes TAB, you have to choose "3D", else it will not work. 220 | Before pushing "Generate" in the deforum extention, prime the communication by inserting a Positive and a Negative prompt in the Deforumation GUI. 221 | 222 | To apply any text changes, you then have to push the "SAVE PROMPTS" button. 223 | You may also set any strength value or other values in beforehand. Also, moving any sliders or pushing any buttons will automatically save all other values (prompts included). The file that is being saved is located inside the deforumation folder (deforumation_settings.txt), and will keep you settings during a restarts. 224 | 225 | Now that this is done, push the "Generate" button in the Deforum extention. 226 | You may now play around with all the values (Panning, Rotating, Tilting, Zoom, Strength Value, CFG value, Sample steps, and of course Prompts, positive and negative) as deforum keeps generating images and applying the new values. 227 | 228 | !!!BE AWARE!!! 229 | Deforumation now adds the values to any scheduled motion. That means that if you have scheduled ANY motions inside of Deforum, like "Translation X" or "Rotation 3D Y", or whatever, they will be added to your manual values done through Deforumation. Be aware that "Translation Z" is by default set to "0:(1.75)"... If you don't want this influence, and only want Deforumation to controll all values, you need to set this to 0:(0). We added this feature, because we think you still want to add a musical flow through the Deforum scheduling. 230 | 231 | 232 | ![img](github_images/output.gif) 233 | 234 |
235 | 236 | 237 |
238 | Interface 239 | 240 | ## Interface 241 | ![img](github_images/newinterface5.png) 242 | 243 | As we talked about before, all motion scheduled values in Deforum are added to the manual motions done through Deforumation... with one exception, and that is the "Strength Value". This value has a specific check box ("USE DEFORUMATION"), which can be turned on and off during rendering to switch between full Deforum controll or Deforumation strength controll. This means, that if you are using Deforum to schedule a beat/pulse throughout your video, you can choose to go manual (overriding the the Deforum strength schedule, and vice versa). 244 | 245 | There are alot of controls, but here comes the basics: 246 | 247 | **Panning** 248 | 249 | ![img](github_images/panning.PNG) 250 | 251 | The buttons will move the camera. So if you push the left arrow, the camera will go left, and the "object" will pan right... etc 252 | 253 | Think of yourself being the eyes (the camera view) and the image that you see... so if you push the left button, then it's like YOU are sidestepping left... etc 254 | 255 | The "0.2" box decides how much of the value will be applied when you push a button. 256 | 257 | **Rotation** 258 | 259 | ![img](github_images/rotation.PNG) 260 | 261 | Think of yourself being the eyes (the camera view) and the image that you see... so if you push the left button, then you'r head will turn left... etc 262 | 263 | **Arming On and Off** 264 | 265 | The panning buttons have 2 modes, "ARMED" or "NOT ARMED", which can be switched between by pushing the small button above the "0.2 box": 266 | 267 | ARMED: ![img](github_images/arm_on.bmp) 268 | 269 | NOT ARMED: ![img](github_images/arm_off.bmp) 270 | 271 | In ARMED mode, the values that you choose through the pann buttons, will be a guide for the "NOT ARMED" values. So the ARMED and the NOT ARMED mode can have totally separate values. 272 | When you then push the big ZERO-icon in the middle: 273 | 274 | ![img](github_images/zero.bmp) 275 | 276 | Your current NOT ARMED values will go towards your ARMED values. And they will do it in the number of frames that you have specified in the "0-Steps" input box. 277 | 278 | **Tilt** 279 | 280 | The "0.2" box decides how much of the value will be applied when you push a button. 281 | 282 | ![img](github_images/tilt.PNG) 283 | 284 | Tilt is tilt... It will rotate the image clock or counter clock-wise. 285 | 286 | The "1.0" box decides how much of the value will be applied when you push a button. 287 | 288 | **Pause and Rewind** 289 | 290 | ![img](github_images/rewindforward.PNG) 291 | 292 | Deforumation allows you to rewind to a given frame, and gives you the ability to start generating from that given frame. This is good for when something in your creativity "goes bananas". Maybe that clown shouldn't have appeard all of a sudden ;P 293 | 294 | This part is useful to rewind and forward througout a rendering. When you have started a rendering, you can look at the current image by pressing the "Show current image" or you can also click anywhere else that is bnot a button on the GUI, to update the image. 295 | 296 | A suggestion before using any of these option is to push the "PUSH TO PAUSE RENDERING BUTTON". The rendering will pause and you can more easily explore the functionalities. 297 | 298 | The "left-arrow"-button shows you the image previous to the current, and the "right-arrow"-button" shows you the next image to the current. 299 | 300 | Typing a frame number in the input box and pushing RETURN will directly transport you to that fram (if it exists). 301 | 302 | The "double-left-arrow" will jump to your closest saved prompt towards the beginning relative to your current frame, and the "double-right-arrow" will jump to your closest saved prompt towards the end relative to your current frame. 303 | 304 | 305 | ![img](github_images/resume.png) 306 | 307 | When you know you did a misstake, start by pressing the "PUSH TO PAUS RENDERING"-button. Then click "Show current image"-button. This will give you the current image, and the current actual frame number. Use the arrows to rewind or forward... or you could just type in a frame number and press enter to jump to that frame... When you found the frame where you want to resume rendering from, press the "Set current image"-button, and then, to resume rendering, push the "PUSH TO RESUME RENDERING"-button. EASY!!! 308 | 309 | **Prompts** 310 | 311 | Pushing the "SAVE PROMPTS" button will save your current prompts (positives and negative), as files inside the "prompts" folde in your deforumation folder. Depending on your current generation (timestring), seperate files will be saved for that particular "project". That means that your prompts can be recalled during a generation of a specific project. E.g. Push "SAVE PROMPT" on fram 0, then on fram 50 change your prompts, and push again "SAVE PROMPTS", and they will update as you rewind/forward throughout you generated frames... You'll get a hang of it ;) (Else ask in the discord). 312 | 313 | **Replay** 314 | 315 | ![img](github_images/replay.png) 316 | 317 | During a generation session, you can directly watched any range of images, by inserting the range you want to play, and then pressing the Play button. 318 | 319 | 320 | ![img](github_images/smile.gif) 321 | 322 | To change the seed, just type a new seed in the seed-input box, and push return. It will then be loyal to whatever you have choosen in the Deforum GUI, iterative, etc. 323 | 324 | 325 | **ControlNet** 326 | 327 | ![img](github_images/controlnet.png) 328 | 329 | Deforumation can control Deforum's 1:st ControlNet (CN Model1) values. They are only active if the ControlNet in Deforum is Enabled. 330 | 331 |
332 | 333 | 334 | 335 | 336 |
337 | Example 338 | 339 | ## Example 340 | Here is an example of LIVE prompt changing for facial expression during rendering. 341 | 342 | Positive Prompt: Beatifull (smiling:0.1), bear girl, focus on face 343 | 344 | Here we just increase the "(smiling:0.1)" value upwards. 345 | 346 | 347 | 348 |
349 | 350 | 351 | 352 | 353 |
354 | A tool for learning 355 | 356 | ## A tool for learning 357 | Deforumation is a perfect tool to learn how different parameters, like Steps, Strength Value and CFG scale, because, in a combination they affect the image generation over time. The best way (I have found, to get as a stable outcome as possible with all other settings you have in Deforum), is to know your values. 358 | 359 | One way to achieve this is to have No motion at all, and make every render not go into "Bananas"... Because the most effective values differ alot between samplers, checkpoints, SD VAE's and all other specific settings that you are currently having. Get a feel of what values, keep a balance with your current choices. Note them down, and play around ;P 360 | 361 |
362 | 363 | 364 | 365 |
366 | Tips and tricks 367 | 368 | ## Tips and tricks 369 | 370 | - Make good use of the PAUS and REWIND functionality. If something is not being generated correctly, you can always redo. 371 | 372 | - Experiment with all the values, in order to understand what happens... That is the best way of learning. 373 | 374 | 375 |
376 | 377 |
378 | Examples of using Deforumation 379 | 380 | ## Examples of using Deforumation (Give a shout if you want to be here) 381 | 382 | By Lainol, Live prompting, facial expression: 383 | 384 | [![Watch the video](github_images/Linol_1.PNG)](https://www.youtube.com/watch?v=UKYZEQVljRE) 385 | 386 | ## Example 2 387 | 388 | By Lainol, Live prompting. 389 | 390 | Ai-xite. 391 | 392 | [![Watch the video](github_images/aixite.png)](https://youtu.be/YH0Q8J1NjIA) 393 | 394 | 395 |
396 | 397 |
398 | Thoughts 399 | 400 | ## Last thoughts 401 | There might be an ongoing discussions on how to implement this into Deforum, so that updates will be more smoth and accordance with Deforum... As of now it remains a Hack... Never the less, we encourage users to test Deforumation, and understand how vital this concept is for creating anything with precision (not looking like an LSD trip). Please post videos, tutorials or, whatever, whith how you use Deforum, through Deforumation to your advantage. Join the r/deforumation channel (https://www.reddit.com/r/deforumation/). 402 | 403 |
404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | -------------------------------------------------------------------------------- /ReadMe_Deforum_Licensing.txt: -------------------------------------------------------------------------------- 1 | In order to accomadate Deforum GNU AFFERO GENERAL PUBLIC LICENSE V3 2 | I we are including the files that have been modified in order for out GUI to communicate with Deforum: 3 | render.py 4 | animation.py 5 | 6 | We also included mediator.py which is a bridge between Deforum and Deforumation (Our GUI). 7 | We have not included our GUI (deforumation.py, where all the actual original work is being made to create the graphical interface) 8 | Deforumation.py which mainly consists of the GUI to controlling Deforum, communicates with the mediator to receive relevant information 9 | on what is going on in the generation of images that Deforum produces. I sometimes also gives Deforum instructions how to behave, through the mediator. 10 | 11 | Anyone can build their own connection/GUI through the publicly available mediator.py if they choose so. 12 | 13 | In The patreon wall that we have, the only file that is not released on github publically, is deforumation.py (our GUI). -------------------------------------------------------------------------------- /Version_0.7.6/Deforum_version/Named_Pipes_version_of_deforum/deforum-for-automatic1111-webui.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/Deforum_version/Named_Pipes_version_of_deforum/deforum-for-automatic1111-webui.zip -------------------------------------------------------------------------------- /Version_0.7.6/Deforum_version/Websockets_version_of_deforum/deforum-for-automatic1111-webui.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/Deforum_version/Websockets_version_of_deforum/deforum-for-automatic1111-webui.zip -------------------------------------------------------------------------------- /Version_0.7.6/ReadMe_Deforum_Licensing.txt: -------------------------------------------------------------------------------- 1 | In order to accomadate Deforum GNU AFFERO GENERAL PUBLIC LICENSE V3 2 | I we are including the files that have been modified in order for out GUI to communicate with Deforum: 3 | render.py 4 | animation.py 5 | 6 | We also included mediator.py which is a bridge between Deforum and Deforumation (Our GUI). 7 | We have not included our GUI (deforumation.py, where all the actual original work is being made to create the graphical interface) 8 | Deforumation.py which mainly consists of the GUI to controlling Deforum, communicates with the mediator to receive relevant information 9 | on what is going on in the generation of images that Deforum produces. I sometimes also gives Deforum instructions how to behave, through the mediator. 10 | 11 | Anyone can build their own connection/GUI through the publicly available mediator.py if they choose so. 12 | 13 | In The patreon wall that we have, the only file that is not released on github publically, is deforumation.py (our GUI). -------------------------------------------------------------------------------- /Version_0.7.6/ReadMe_Installation_and_running_Deforumation.txt: -------------------------------------------------------------------------------- 1 | The following version is for Deforum version 0.7.6 2 | ------------------------------------------------------------- 3 | Pre-requisits: 4 | -------------- 5 | Python 3.10 or higher... Deforumation was developed to work with python version 3.10 (version 3.11 or 3.12 have not been validated or tested). 6 | 7 | Installation: 8 | ------------- 9 | Install dependencies by opening a terminal in the root folder of deforumation, and then run: python -m pip install -r requirements.txt 10 | or (for Windows users), run the "run_me_first_install_requirements.bat" file. 11 | !! For MAC users you will get an error that pywin32 can not be found or something... Ignor that error, because, it is only used for the "named pipes", 12 | version of Deforumation (which MAC users will not use, and so are not affected by not having installed pywin32). 13 | 14 | For MAC users, copy the websocket version of Deforum ("Deforum_version\Websockets_version_of_deforum\deforum-for-automatic1111-webui" (inside the deforum-for-automatic1111-webui.zip file)) 15 | to your extentions folder in Automatic1111. (Be sure to delete any old folder of Deforum, or overwrite the old one when asked.) 16 | Then, after installing deforumation, start the mediator with "python mediator_ws.py" and then "python deforumation_ws.py" 17 | 18 | For users that want to use named pipes version (recommended for Windows and Linux users) of deforum/deforumation, copy the folder "Deforum_version\Named_Pipes_version_of_deforum\deforum-for-automatic1111-webui" (Also needs to be unpacked from deforum-for-automatic1111-webui.zip file). 19 | to your extentions folder in Automatic1111. (Be sure to delete any old folder of Deforum, or overwrite the old one when asked.) 20 | Then, after installing deforumation, start it normally with: "python mediator.py piped" and "python deforumation.py piped" or for Windows users, run the bat-script called "Deforumation_start_named_pipes.bat". 21 | 22 | For users that want to use websocket version of deforum/deforumation, copy the folder (unpack the deforum-for-automatic1111-webui.zip file) "Deforum_version\Websockets_version_of_deforum\deforum-for-automatic1111-webui" to your extentions folder in Automatic1111. (Be sure to delete any old folder of Deforum, or overwrite the old one when asked.) 23 | Then, after installing deforumation, start it normally with: "python mediator.py" and "python deforumation.py" or for Windows users, run the bat-script 24 | called "Deforumation_start_websockets.bat". The named pipes version is recommended before the websocket version, and should only be used if you 25 | are having problems with named pipes (which I doubt). 26 | 27 | For colab users you should use the files located inside "./deforumation/colab_files". Please look at: https://github.com/rozidev/deforumation-golab 28 | The process is not straight forward, so if you are having any issues, please see the Deforumation discord server @ https://discord.gg/rbKFVh9v87 and don't be afraid to ask for help. 29 | 30 | Need further help? 31 | Ask in the Discord server. 32 | https://discord.gg/rbKFVh9v87 33 | -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/Deforumation_start_named_pipes.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | start python mediator.py pipes 3 | timeout /t 0.5 /nobreak > NUL 4 | start python deforumation.py pipes -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/Deforumation_start_websockets.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | start python mediator.py 3 | timeout /t 0.5 /nobreak > NUL 4 | start python deforumation.py -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/Dirty_Fix_To_Fix_Freeze_Problem_old_and_probably_obsolete/autoencoder.py: -------------------------------------------------------------------------------- 1 | import threading 2 | import torch 3 | import pytorch_lightning as pl 4 | import torch.nn.functional as F 5 | from contextlib import contextmanager 6 | 7 | from ldm.modules.diffusionmodules.model import Encoder, Decoder 8 | from ldm.modules.distributions.distributions import DiagonalGaussianDistribution 9 | 10 | from ldm.util import instantiate_from_config 11 | from ldm.modules.ema import LitEma 12 | 13 | 14 | class AutoencoderKL(pl.LightningModule): 15 | def __init__(self, 16 | ddconfig, 17 | lossconfig, 18 | embed_dim, 19 | ckpt_path=None, 20 | ignore_keys=[], 21 | image_key="image", 22 | colorize_nlabels=None, 23 | monitor=None, 24 | ema_decay=None, 25 | learn_logvar=False 26 | ): 27 | super().__init__() 28 | 29 | self.learn_logvar = learn_logvar 30 | self.image_key = image_key 31 | self._lock = threading.Lock() 32 | self.encoder = Encoder(**ddconfig) 33 | self.decoder = Decoder(**ddconfig) 34 | self.loss = instantiate_from_config(lossconfig) 35 | assert ddconfig["double_z"] 36 | self.quant_conv = torch.nn.Conv2d(2*ddconfig["z_channels"], 2*embed_dim, 1) 37 | self.post_quant_conv = torch.nn.Conv2d(embed_dim, ddconfig["z_channels"], 1) 38 | self.embed_dim = embed_dim 39 | if colorize_nlabels is not None: 40 | assert type(colorize_nlabels)==int 41 | self.register_buffer("colorize", torch.randn(3, colorize_nlabels, 1, 1)) 42 | if monitor is not None: 43 | self.monitor = monitor 44 | 45 | self.use_ema = ema_decay is not None 46 | if self.use_ema: 47 | self.ema_decay = ema_decay 48 | assert 0. < ema_decay < 1. 49 | self.model_ema = LitEma(self, decay=ema_decay) 50 | print(f"Keeping EMAs of {len(list(self.model_ema.buffers()))}.") 51 | 52 | if ckpt_path is not None: 53 | self.init_from_ckpt(ckpt_path, ignore_keys=ignore_keys) 54 | 55 | def init_from_ckpt(self, path, ignore_keys=list()): 56 | sd = torch.load(path, map_location="cpu")["state_dict"] 57 | keys = list(sd.keys()) 58 | for k in keys: 59 | for ik in ignore_keys: 60 | if k.startswith(ik): 61 | print("Deleting key {} from state_dict.".format(k)) 62 | del sd[k] 63 | self.load_state_dict(sd, strict=False) 64 | print(f"Restored from {path}") 65 | 66 | @contextmanager 67 | def ema_scope(self, context=None): 68 | if self.use_ema: 69 | self.model_ema.store(self.parameters()) 70 | self.model_ema.copy_to(self) 71 | if context is not None: 72 | print(f"{context}: Switched to EMA weights") 73 | try: 74 | yield None 75 | finally: 76 | if self.use_ema: 77 | self.model_ema.restore(self.parameters()) 78 | if context is not None: 79 | print(f"{context}: Restored training weights") 80 | 81 | def on_train_batch_end(self, *args, **kwargs): 82 | if self.use_ema: 83 | self.model_ema(self) 84 | 85 | def encode(self, x): 86 | h = self.encoder(x) 87 | moments = self.quant_conv(h) 88 | posterior = DiagonalGaussianDistribution(moments) 89 | return posterior 90 | 91 | def decode(self, z): 92 | with self._lock: 93 | z = self.post_quant_conv(z) 94 | dec = self.decoder(z) 95 | return dec 96 | 97 | def forward(self, input, sample_posterior=True): 98 | posterior = self.encode(input) 99 | if sample_posterior: 100 | z = posterior.sample() 101 | else: 102 | z = posterior.mode() 103 | dec = self.decode(z) 104 | return dec, posterior 105 | 106 | def get_input(self, batch, k): 107 | x = batch[k] 108 | if len(x.shape) == 3: 109 | x = x[..., None] 110 | x = x.permute(0, 3, 1, 2).to(memory_format=torch.contiguous_format).float() 111 | return x 112 | 113 | def training_step(self, batch, batch_idx, optimizer_idx): 114 | inputs = self.get_input(batch, self.image_key) 115 | reconstructions, posterior = self(inputs) 116 | 117 | if optimizer_idx == 0: 118 | # train encoder+decoder+logvar 119 | aeloss, log_dict_ae = self.loss(inputs, reconstructions, posterior, optimizer_idx, self.global_step, 120 | last_layer=self.get_last_layer(), split="train") 121 | self.log("aeloss", aeloss, prog_bar=True, logger=True, on_step=True, on_epoch=True) 122 | self.log_dict(log_dict_ae, prog_bar=False, logger=True, on_step=True, on_epoch=False) 123 | return aeloss 124 | 125 | if optimizer_idx == 1: 126 | # train the discriminator 127 | discloss, log_dict_disc = self.loss(inputs, reconstructions, posterior, optimizer_idx, self.global_step, 128 | last_layer=self.get_last_layer(), split="train") 129 | 130 | self.log("discloss", discloss, prog_bar=True, logger=True, on_step=True, on_epoch=True) 131 | self.log_dict(log_dict_disc, prog_bar=False, logger=True, on_step=True, on_epoch=False) 132 | return discloss 133 | 134 | def validation_step(self, batch, batch_idx): 135 | log_dict = self._validation_step(batch, batch_idx) 136 | with self.ema_scope(): 137 | log_dict_ema = self._validation_step(batch, batch_idx, postfix="_ema") 138 | return log_dict 139 | 140 | def _validation_step(self, batch, batch_idx, postfix=""): 141 | inputs = self.get_input(batch, self.image_key) 142 | reconstructions, posterior = self(inputs) 143 | aeloss, log_dict_ae = self.loss(inputs, reconstructions, posterior, 0, self.global_step, 144 | last_layer=self.get_last_layer(), split="val"+postfix) 145 | 146 | discloss, log_dict_disc = self.loss(inputs, reconstructions, posterior, 1, self.global_step, 147 | last_layer=self.get_last_layer(), split="val"+postfix) 148 | 149 | self.log(f"val{postfix}/rec_loss", log_dict_ae[f"val{postfix}/rec_loss"]) 150 | self.log_dict(log_dict_ae) 151 | self.log_dict(log_dict_disc) 152 | return self.log_dict 153 | 154 | def configure_optimizers(self): 155 | lr = self.learning_rate 156 | ae_params_list = list(self.encoder.parameters()) + list(self.decoder.parameters()) + list( 157 | self.quant_conv.parameters()) + list(self.post_quant_conv.parameters()) 158 | if self.learn_logvar: 159 | print(f"{self.__class__.__name__}: Learning logvar") 160 | ae_params_list.append(self.loss.logvar) 161 | opt_ae = torch.optim.Adam(ae_params_list, 162 | lr=lr, betas=(0.5, 0.9)) 163 | opt_disc = torch.optim.Adam(self.loss.discriminator.parameters(), 164 | lr=lr, betas=(0.5, 0.9)) 165 | return [opt_ae, opt_disc], [] 166 | 167 | def get_last_layer(self): 168 | return self.decoder.conv_out.weight 169 | 170 | @torch.no_grad() 171 | def log_images(self, batch, only_inputs=False, log_ema=False, **kwargs): 172 | log = dict() 173 | x = self.get_input(batch, self.image_key) 174 | x = x.to(self.device) 175 | if not only_inputs: 176 | xrec, posterior = self(x) 177 | if x.shape[1] > 3: 178 | # colorize with random projection 179 | assert xrec.shape[1] > 3 180 | x = self.to_rgb(x) 181 | xrec = self.to_rgb(xrec) 182 | log["samples"] = self.decode(torch.randn_like(posterior.sample())) 183 | log["reconstructions"] = xrec 184 | if log_ema or self.use_ema: 185 | with self.ema_scope(): 186 | xrec_ema, posterior_ema = self(x) 187 | if x.shape[1] > 3: 188 | # colorize with random projection 189 | assert xrec_ema.shape[1] > 3 190 | xrec_ema = self.to_rgb(xrec_ema) 191 | log["samples_ema"] = self.decode(torch.randn_like(posterior_ema.sample())) 192 | log["reconstructions_ema"] = xrec_ema 193 | log["inputs"] = x 194 | return log 195 | 196 | def to_rgb(self, x): 197 | assert self.image_key == "segmentation" 198 | if not hasattr(self, "colorize"): 199 | self.register_buffer("colorize", torch.randn(3, x.shape[1], 1, 1).to(x)) 200 | x = F.conv2d(x, weight=self.colorize) 201 | x = 2.*(x-x.min())/(x.max()-x.min()) - 1. 202 | return x 203 | 204 | 205 | class IdentityFirstStage(torch.nn.Module): 206 | def __init__(self, *args, vq_interface=False, **kwargs): 207 | self.vq_interface = vq_interface 208 | super().__init__() 209 | 210 | def encode(self, x, *args, **kwargs): 211 | return x 212 | 213 | def decode(self, x, *args, **kwargs): 214 | return x 215 | 216 | def quantize(self, x, *args, **kwargs): 217 | if self.vq_interface: 218 | return x, None, [None, None, None] 219 | return x 220 | 221 | def forward(self, x, *args, **kwargs): 222 | return x 223 | 224 | -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/Dirty_Fix_To_Fix_Freeze_Problem_old_and_probably_obsolete/deforumation_quick_fix.txt: -------------------------------------------------------------------------------- 1 | 2023-05-21 2 | ------------------------------------------- 3 | Ref: As noted from (https://github.com/vladmandic/automatic/issues/340). 4 | 5 | One thing that could be the root to the freeze, is a race condition that could be created 6 | between "../modules/processing.py:decode_first_stage" (used by the Live Previewer) and "../models/autoencoder:decode 7 | 8 | It seems to have been more notible when using Torch 2.0+ .... Maybe because it is faster and there are more possibility 9 | to create this race condition???? 10 | 11 | So anyone that experience freezing could try the following steps: 12 | 13 | 1. Use the modified "autoencoder.py" file in this folder to replacce: ..\stable-diffusion-webui\repositories\stable-diffusion-stability-ai\ldm\models\autoencoder.py 14 | -- This adds a thread lock, to prevent the race condition. 15 | 16 | 2. Force an upgrade to the latest version of Gradio (as of speaking, 3.31.0) 17 | Open a command line window and standing in the "..\stable-diffusion-webui\venv\Scripts\" folder, activate the python environment by running the "activate.bat" file from your command linme. 18 | 19 | You should now have a new prompt with "(venv)" infron of it (meaning you have entered the environment). 20 | From here run the command: pip install --upgrade gradio 21 | 22 | 3. Open up requirements_versions.txt located in the ..\stable-diffusion-webui\ root, and change "gradio==3.29.0" to "gradio" 23 | 4. Open up requirements.txt located in the ..\stable-diffusion-webui\ root, and change "gradio==3.29.0" to "gradio" 24 | 25 | 2023-05-26 !!!! VERY IMPORTANT !!!! 26 | ----------------------------------------------------------------- 27 | We have noticed that websocket 11.xxx is a major cause for the current freeze problem. We recommend using deforumation with websocket==10.4 28 | Check your current websocket version, by typing: python -m websockets --version 29 | in a CMD window (windows) or terminal (linux). 30 | If you have "websockets 11.xx.xx", then downgrade to 10.4 through these two commands: 31 | pip uninstall websockets 32 | pip install websockets==10.4 33 | 34 | ------------------------------------------------------------------------------------------------------------ 35 | That should be it. Kill the cmd window, and start: webui-user.bat or what ever you start-up file is. And restart/start "mediator.py" and then "deforumation.py" normally. 36 | -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/README.md: -------------------------------------------------------------------------------- 1 | 2 | `DISCLAIMER!!!` 3 | =============================================== 4 | `!!!THERE WILL BE NO DEFORUM SUPPORT IF YOU USE THIS EXTENSION!!!` 5 | =============================================== 6 | --------------------------------------------------------------------------------------------------------------------------------------- 7 | 8 | Deforumation: Unofficial Extension for Deforum 9 | =============================================== 10 | 11 | **IMPORTANT: No official Deforum support will be provided if you use this extension.** 12 | 13 | 14 | 15 | Table of Contents 16 | ----------------- 17 | 1. [Introduction](#introduction) 18 | 2. [Prerequisites](#prerequisites) 19 | 3. [Key Features](#key-features) 20 | 4. [Installation Guide](#installation-guide) 21 | 5. [Installation Tutorial](#installation-Tutorial) 22 | 6. [Compatibility](#compatibility) 23 | 7. [Usage and Tips](#usage-and-tips) 24 | 8. [Disclaimer](#disclaimer) 25 | 9. [Discord Channel](#Discord-Channel) 26 | 10. [Ongoing Work](#Ongoing-Work) 27 | 11. [in-depth information](#in-depth-information) 28 | 12. [patreon](#patreon) 29 | 30 | 31 | 32 | 33 | Support our work via Patreon or buymeacoffee 34 | =============================================== 35 | [Deforumation Patreon](https://www.patreon.com/Deforumation) 36 | ------------ 37 | [buymeacoffee.com](https://www.buymeacoffee.com/deforumation) 38 | ------------ 39 | Deforumation is a free tool for everyone to use. We appreciate all and any donations/support to keep Deforumation up to date and adding new features together with the community. 40 | 41 | 42 | 43 | 44 | Latest version / features 45 | ----------------- 46 | [Latest version](#Latest-version) (2023-06-18) 47 | 48 | 49 | Introduction 50 | ------------ 51 | Deforumation is an unofficial extension for Deforum that provides a Graphical User Interface (GUI) to remotely control Deforum 3D motions, zoom and angle , strength value (toggle to use deforum strenght schedule), CFG Scale, sampler steps, seed, cadense scale, noise values, parameters for use up to five controlnets, and prompts in real-time. It also offers pausing, rewinding, forwarding, and resuming by setting current image to fix any undesired outcomes during the rendering process. 52 | 53 | Recently added features are checkboxes for enable / disable fuctions from Deforumation. Checkboxes are added to Prompt, Strenght value, CFG scale, Cadense scale, Noise values, camera panning and camera rotation. This makes it possible to apply sceduling to any of those values from Deforum or from Parseq. 54 | Also added customizable curves for use with armed motions controls. Parameters for up to five controlnets. Cadence Re-Scheduler, this is a module to recalculate the 55 | Cadence Schedule due to "tween" pictures not reacting to schedueled values. 56 | 57 | Key Features 58 | ------------ 59 | - Live View (separate window) of the rendered pictures. 60 | - Separate prompting input boxes with prioritising possibility 61 | - Controlling movements while rendering, now with armed movements and presetted curves 62 | - Live manipulation of key values that effects the animation 63 | - Live manipulation of controlnets 64 | - Pause, rewind, and redo functions 65 | - Ability to import parseq json files to use as guide 66 | - Two different communication protocols, websockets and named pipes. This is due to problem with freezing renders. 67 | 68 | Prerequisites 69 | ------------ 70 | 1. Local instance of SD ([AUTOMATIC1111/stable-diffusion-webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui)) 71 | 2. Installed Deforum Extension for AUTOMATIC1111 ([deforum-art/deforum-for-automatic1111-webui](https://github.com/deforum-art/deforum-for-automatic1111-webui)) 72 | 73 | Installation Guide 74 | ------------------- 75 | 1. **Clone or download** the git repository `git clone https://github.com/Rakile/deforumation` (https://github.com/Rakile/deforumation) and unpack the zip file. Keep deforumation folder outside your `"stable-diffusion-webui"` path. 76 | 2. **Replace files** (render.py, animation.py, deforum_mediator.py) in the Automatic1111 path ".\extensions\deforum-for-automatic1111-webui\scripts\deforum_helpers\" with the downloaded files from Deforumation. To use the "named pipes" protocol the `"mediator".py` file must be copied from the `"deforum_mediator_named_pipes"` folder to your `"\\stable-diffusion-webui-02\extensions\deforum-for-automatic1111-webui\scripts\deforum_helpers"` 77 | 3. **Install dependencies** by running `python -m pip install -r requirements.txt` or using the `"run_me_first_install_requirements.bat"` file. 78 | 4. **!!IMPORTANT!!** Check that you have installed websocket version 10.4.(the correct version is included in the reqirements.txt) Do this by running the command: python -m websockets --version 79 | in a CMD (command line window) window. People have noticed that python websocket library, with a version higher or equal to 11.0, makes Deforum and Deforumation freeze. 80 | See (https://github.com/Rakile/deforumation/blob/main/Dirty_Fix_To_Fix_Freeze_Problem/deforumation_quick_fix.txt) for more information. 81 | 5. To start Deforumation using websocket protocol **Run the Mediator** (mediator.py) `H:\named\deforumation>python mediator.py` and the **Deforumation GUI** (deforumation.py) `H:\named\deforumation>python deforumation.py` in CMD inside deforumation path. Or use the `"Deforumation_start_websockets.bat"` file. 82 | 6. To start Deforumation using named pipes protocol **Run the Mediator** (mediator.py) `H:\named\deforumation>python mediator.py pipes` and the **Deforumation GUI** (deforumation.py) `H:\named\deforumation>python deforumation.py pipes` in CMD inside deforumation path. Or use the `"Deforumation_start_named_pipes.bat"` file. 83 | 7. To use the `"named pipes"` protocol the correct `"mediator".py` file must be copied from the `"deforum_mediator_named_pipes"` folder to your `"\\stable-diffusion-webui-02\extensions\deforum-for-automatic1111-webui\scripts\deforum_helpers"` 84 | 8. **Set to 3D in keyframes TAB** In the Deforum extention in the `Keyframes TAB, you have to choose "3D"`, else it will not work. 85 | 86 | Installation Tutorial 87 | ------------- 88 | [Installation Tutorial](https://youtu.be/7KmtmPlhzNs) (Tutorial is for websocket protocol, follow the above installation guide to use named pipes protocol) 89 | 90 | Compatibility 91 | ------------- 92 | Deforumation may not be compatible with all versions of Deforum. For now Deforum does not have the communication module in there core files. 93 | For now we try to update Deforumation as Deforum is updated. 94 | 95 | Usage and Tips 96 | -------------- 97 | Deforumation is a valuable tool for understanding how different parameters affect the image generation process. However, it is essential to remember that using Deforumation may result in some issues, as it is not an officially supported extension. 98 | 99 | 100 | - In the Deforum extention in the Keyframes TAB, you have to choose "3D", else it will not work. Before pushing "Generate" in the deforum extention, prime the communication by inserting a Positive and a Negative prompt in the Deforumation GUI. 101 | - Be sure that your Deforum extension does work berfore installing Deforumation. 102 | - Make sure the Mediator is running to ensure proper communication between Deforum and Deforumation. 103 | - Experiment with different settings to find the most effective values for your specific project. 104 | - Change "live preview" settings in automatic1111 to draft for faster rendering. 105 | - Check the "LIVE RENDER" box in deforumation to se generated frames. 106 | 107 | 108 | Disclaimer 109 | ---------- 110 | By using Deforumation, you understand and acknowledge that it is an unofficial, third-party extension for Deforum. There will be no official support provided for Deforum when using this extension. Use it at your own risk. 111 | 112 | 113 | 114 | Discord Channel 115 | ---------- 116 | 117 | [Welcome To Deforumation] (https://discord.gg/rbKFVh9v87) 118 | 119 | 120 | Ongoing Work 121 | ---------- 122 | 123 | Below you se the draft for the new Deforumation UI. Many new features like the ability to customize the layout 124 | and choose what values you work with during the animation rendering process. There will also be support to control 125 | the movements using a joystick or game-pad. The paus, rewind and redo function will be the "animation player". 126 | 127 | The prompting can be done in traditional way by having the complete prompt in one prompt-input box. 128 | But as shown in the UI you will also have the ability to make separate prompting input boxes(and adjust the prio) for easier prompting. 129 | 130 | And to the left there will be a drop down list for automated macros, like facial expression styles, automated blinking. 131 | Or whatever your imagination can come up with. 132 | 133 | ![img](github_images/deforumation_design_01.jpg) 134 | 135 | 136 | 137 | 138 | Latest version 139 | ---------- 140 |
141 | Latest Version Info 142 | 143 | 2023-05-15 144 | Lots of added stuff 145 | - Gentle Zero can now go from any motion to any other motion in panning and rotation values 146 | - ControlNet in Deforum, can now be controlled by Deforumation 147 | - Live Render can now replay a range of images (no stitching), to get a fast view of how the animation is going to look 148 | 149 | 150 |
151 | 152 |
153 | Latest Version Info 154 | 155 | 2023-05-03 (later in the evening) 156 | 157 | - Introducing another "Gentle Zero" for rotation. It works separate from "Gentle Zero" for panning. 158 | 159 | ![img](github_images/current_version_gentle_zero_rotation.png) 160 | 161 | 162 |
163 | 164 |
165 | Latest Version Info 166 | 167 | 2023-05-03 168 | 169 | - Separate prompting input boxes with prioritising possibility 170 | 171 | - All prompts can now be minimized, making the window smaller, 172 | and maybe some people will find this easier to work with. 173 | 174 | ![img](github_images/current_version.png) 175 | 176 | 177 |
178 | 179 | 180 | In-depth information 181 | ---------- 182 | 183 | 184 |
185 | How it works 186 | ## How it works 187 | Watch this video to get a feeling of how to use Deforumation... or read on below. 188 | [![Watch the video](github_images/Deforumation_Tutorial.png)](https://www.youtube.com/watch?v=v1h2jo3f5U4) 189 | 190 | ## Recommended setting 191 | 192 | In settings, Live previews recommends this setting. This gives you better visual feedback. 193 | 194 | ![img](github_images/Live_preview.png) 195 | 196 | 197 | In the Deforum extention in the Keyframes TAB, you have to choose "3D", else it will not work. 198 | Before pushing "Generate" in the deforum extention, prime the communication by inserting a Positive and a Negative prompt in the Deforumation GUI. 199 | 200 | To apply any text changes, you then have to push the "SAVE PROMPTS" button. 201 | You may also set any strength value or other values in beforehand. Also, moving any sliders or pushing any buttons will automatically save all other values (prompts included). The file that is being saved is located inside the deforumation folder (deforumation_settings.txt), and will keep you settings during a restarts. 202 | 203 | Now that this is done, push the "Generate" button in the Deforum extention. 204 | You may now play around with all the values (Panning, Rotating, Tilting, Zoom, Strength Value, CFG value, Sample steps, and of course Prompts, positive and negative) as deforum keeps generating images and applying the new values. 205 | 206 | !!!BE AWARE!!! 207 | Deforumation now adds the values to any scheduled motion. That means that if you have scheduled ANY motions inside of Deforum, like "Translation X" or "Rotation 3D Y", or whatever, they will be added to your manual values done through Deforumation. Be aware that "Translation Z" is by default set to "0:(1.75)"... If you don't want this influence, and only want Deforumation to controll all values, you need to set this to 0:(0). We added this feature, because we think you still want to add a musical flow through the Deforum scheduling. 208 | 209 | 210 | ![img](github_images/output.gif) 211 | 212 |
213 | 214 | 215 |
216 | Interface 217 | 218 | ## Interface 219 | ![img](github_images/newinterface5.png) 220 | 221 | As we talked about before, all motion scheduled values in Deforum are added to the manual motions done through Deforumation... with one exception, and that is the "Strength Value". This value has a specific check box ("USE DEFORUMATION"), which can be turned on and off during rendering to switch between full Deforum controll or Deforumation strength controll. This means, that if you are using Deforum to schedule a beat/pulse throughout your video, you can choose to go manual (overriding the the Deforum strength schedule, and vice versa). 222 | 223 | There are alot of controls, but here comes the basics: 224 | 225 | **Panning** 226 | 227 | ![img](github_images/panning.PNG) 228 | 229 | The buttons will move the camera. So if you push the left arrow, the camera will go left, and the "object" will pan right... etc 230 | 231 | Think of yourself being the eyes (the camera view) and the image that you see... so if you push the left button, then it's like YOU are sidestepping left... etc 232 | 233 | The "0.2" box decides how much of the value will be applied when you push a button. 234 | 235 | **Rotation** 236 | 237 | ![img](github_images/rotation.PNG) 238 | 239 | Think of yourself being the eyes (the camera view) and the image that you see... so if you push the left button, then you'r head will turn left... etc 240 | 241 | **Arming On and Off** 242 | 243 | The panning buttons have 2 modes, "ARMED" or "NOT ARMED", which can be switched between by pushing the small button above the "0.2 box": 244 | 245 | ARMED: ![img](github_images/arm_on.bmp) 246 | 247 | NOT ARMED: ![img](github_images/arm_off.bmp) 248 | 249 | In ARMED mode, the values that you choose through the pann buttons, will be a guide for the "NOT ARMED" values. So the ARMED and the NOT ARMED mode can have totally separate values. 250 | When you then push the big ZERO-icon in the middle: 251 | 252 | ![img](github_images/zero.bmp) 253 | 254 | Your current NOT ARMED values will go towards your ARMED values. And they will do it in the number of frames that you have specified in the "0-Steps" input box. 255 | 256 | **Tilt** 257 | 258 | The "0.2" box decides how much of the value will be applied when you push a button. 259 | 260 | ![img](github_images/tilt.PNG) 261 | 262 | Tilt is tilt... It will rotate the image clock or counter clock-wise. 263 | 264 | The "1.0" box decides how much of the value will be applied when you push a button. 265 | 266 | **Pause and Rewind** 267 | 268 | ![img](github_images/rewindforward.PNG) 269 | 270 | Deforumation allows you to rewind to a given frame, and gives you the ability to start generating from that given frame. This is good for when something in your creativity "goes bananas". Maybe that clown shouldn't have appeard all of a sudden ;P 271 | 272 | This part is useful to rewind and forward througout a rendering. When you have started a rendering, you can look at the current image by pressing the "Show current image" or you can also click anywhere else that is bnot a button on the GUI, to update the image. 273 | 274 | A suggestion before using any of these option is to push the "PUSH TO PAUSE RENDERING BUTTON". The rendering will pause and you can more easily explore the functionalities. 275 | 276 | The "left-arrow"-button shows you the image previous to the current, and the "right-arrow"-button" shows you the next image to the current. 277 | 278 | Typing a frame number in the input box and pushing RETURN will directly transport you to that fram (if it exists). 279 | 280 | The "double-left-arrow" will jump to your closest saved prompt towards the beginning relative to your current frame, and the "double-right-arrow" will jump to your closest saved prompt towards the end relative to your current frame. 281 | 282 | 283 | ![img](github_images/resume.png) 284 | 285 | When you know you did a misstake, start by pressing the "PUSH TO PAUS RENDERING"-button. Then click "Show current image"-button. This will give you the current image, and the current actual frame number. Use the arrows to rewind or forward... or you could just type in a frame number and press enter to jump to that frame... When you found the frame where you want to resume rendering from, press the "Set current image"-button, and then, to resume rendering, push the "PUSH TO RESUME RENDERING"-button. EASY!!! 286 | 287 | **Prompts** 288 | 289 | Pushing the "SAVE PROMPTS" button will save your current prompts (positives and negative), as files inside the "prompts" folde in your deforumation folder. Depending on your current generation (timestring), seperate files will be saved for that particular "project". That means that your prompts can be recalled during a generation of a specific project. E.g. Push "SAVE PROMPT" on fram 0, then on fram 50 change your prompts, and push again "SAVE PROMPTS", and they will update as you rewind/forward throughout you generated frames... You'll get a hang of it ;) (Else ask in the discord). 290 | 291 | **Replay** 292 | 293 | ![img](github_images/replay.png) 294 | 295 | During a generation session, you can directly watched any range of images, by inserting the range you want to play, and then pressing the Play button. 296 | 297 | 298 | ![img](github_images/smile.gif) 299 | 300 | To change the seed, just type a new seed in the seed-input box, and push return. It will then be loyal to whatever you have choosen in the Deforum GUI, iterative, etc. 301 | 302 | 303 | **ControlNet** 304 | 305 | ![img](github_images/controlnet.png) 306 | 307 | Deforumation can control Deforum's 1:st ControlNet (CN Model1) values. They are only active if the ControlNet in Deforum is Enabled. 308 | 309 |
310 | 311 | 312 | 313 | 314 |
315 | Example 316 | 317 | ## Example 318 | Here is an example of LIVE prompt changing for facial expression during rendering. 319 | 320 | Positive Prompt: Beatifull (smiling:0.1), bear girl, focus on face 321 | 322 | Here we just increase the "(smiling:0.1)" value upwards. 323 | 324 | 325 | 326 |
327 | 328 | 329 | 330 | 331 |
332 | A tool for learning 333 | 334 | ## A tool for learning 335 | Deforumation is a perfect tool to learn how different parameters, like Steps, Strength Value and CFG scale, because, in a combination they affect the image generation over time. The best way (I have found, to get as a stable outcome as possible with all other settings you have in Deforum), is to know your values. 336 | 337 | One way to achieve this is to have No motion at all, and make every render not go into "Bananas"... Because the most effective values differ alot between samplers, checkpoints, SD VAE's and all other specific settings that you are currently having. Get a feel of what values, keep a balance with your current choices. Note them down, and play around ;P 338 | 339 |
340 | 341 | 342 | 343 |
344 | Tips and tricks 345 | 346 | ## Tips and tricks 347 | 348 | - Make good use of the PAUS and REWIND functionality. If something is not being generated correctly, you can always redo. 349 | 350 | - Experiment with all the values, in order to understand what happens... That is the best way of learning. 351 | 352 | 353 |
354 | 355 |
356 | Examples of using Deforumation 357 | 358 | ## Examples of using Deforumation (Give a shout if you want to be here) 359 | 360 | By Lainol, Live prompting, facial expression: 361 | 362 | [![Watch the video](github_images/Linol_1.PNG)](https://www.youtube.com/watch?v=UKYZEQVljRE) 363 | 364 | ## Example 2 365 | 366 | By Lainol, Live prompting. 367 | 368 | Ai-xite. 369 | 370 | [![Watch the video](github_images/aixite.png)](https://youtu.be/YH0Q8J1NjIA) 371 | 372 | 373 |
374 | 375 |
376 | Thoughts 377 | 378 | ## Last thoughts 379 | There might be an ongoing discussions on how to implement this into Deforum, so that updates will be more smoth and accordance with Deforum... As of now it remains a Hack... Never the less, we encourage users to test Deforumation, and understand how vital this concept is for creating anything with precision (not looking like an LSD trip). Please post videos, tutorials or, whatever, whith how you use Deforum, through Deforumation to your advantage. Join the r/deforumation channel (https://www.reddit.com/r/deforumation/). 380 | 381 |
382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/colab_files/animation.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Deforum LLC 2 | # 3 | # This program is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU Affero General Public License as published by 5 | # the Free Software Foundation, version 3 of the License. 6 | # 7 | # This program is distributed in the hope that it will be useful, 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | # GNU General Public License for more details. 11 | # 12 | # You should have received a copy of the GNU Affero General Public License 13 | # along with this program. If not, see . 14 | 15 | # Contact the authors: https://deforum.github.io/ 16 | 17 | import numpy as np 18 | import cv2 19 | import py3d_tools as p3d # this is actually a file in our /src folder! 20 | from functools import reduce 21 | import math 22 | import torch 23 | from einops import rearrange 24 | from modules.shared import state, opts 25 | from .prompt import check_is_number 26 | from .general_utils import debug_print 27 | 28 | #Deforumation_mediator imports/settings 29 | from .deforum_mediator import mediator_getValue, mediator_setValue 30 | usingDeforumation = True 31 | #End settings 32 | 33 | # Webui 34 | #from modules.shared import state, opts 35 | #DEBUG_MODE = opts.data.get("deforum_debug_mode_enabled", False) 36 | 37 | def sample_from_cv2(sample: np.ndarray) -> torch.Tensor: 38 | sample = ((sample.astype(float) / 255.0) * 2) - 1 39 | sample = sample[None].transpose(0, 3, 1, 2).astype(np.float16) 40 | sample = torch.from_numpy(sample) 41 | return sample 42 | 43 | def sample_to_cv2(sample: torch.Tensor, type=np.uint8) -> np.ndarray: 44 | sample_f32 = rearrange(sample.squeeze().cpu().numpy(), "c h w -> h w c").astype(np.float32) 45 | sample_f32 = ((sample_f32 * 0.5) + 0.5).clip(0, 1) 46 | sample_int8 = (sample_f32 * 255) 47 | return sample_int8.astype(type) 48 | 49 | def construct_RotationMatrixHomogenous(rotation_angles): 50 | assert(type(rotation_angles)==list and len(rotation_angles)==3) 51 | RH = np.eye(4,4) 52 | cv2.Rodrigues(np.array(rotation_angles), RH[0:3, 0:3]) 53 | return RH 54 | 55 | # https://en.wikipedia.org/wiki/Rotation_matrix 56 | def getRotationMatrixManual(rotation_angles): 57 | 58 | rotation_angles = [np.deg2rad(x) for x in rotation_angles] 59 | 60 | phi = rotation_angles[0] # around x 61 | gamma = rotation_angles[1] # around y 62 | theta = rotation_angles[2] # around z 63 | 64 | # X rotation 65 | Rphi = np.eye(4,4) 66 | sp = np.sin(phi) 67 | cp = np.cos(phi) 68 | Rphi[1,1] = cp 69 | Rphi[2,2] = Rphi[1,1] 70 | Rphi[1,2] = -sp 71 | Rphi[2,1] = sp 72 | 73 | # Y rotation 74 | Rgamma = np.eye(4,4) 75 | sg = np.sin(gamma) 76 | cg = np.cos(gamma) 77 | Rgamma[0,0] = cg 78 | Rgamma[2,2] = Rgamma[0,0] 79 | Rgamma[0,2] = sg 80 | Rgamma[2,0] = -sg 81 | 82 | # Z rotation (in-image-plane) 83 | Rtheta = np.eye(4,4) 84 | st = np.sin(theta) 85 | ct = np.cos(theta) 86 | Rtheta[0,0] = ct 87 | Rtheta[1,1] = Rtheta[0,0] 88 | Rtheta[0,1] = -st 89 | Rtheta[1,0] = st 90 | 91 | R = reduce(lambda x,y : np.matmul(x,y), [Rphi, Rgamma, Rtheta]) 92 | 93 | return R 94 | 95 | def getPoints_for_PerspectiveTranformEstimation(ptsIn, ptsOut, W, H, sidelength): 96 | 97 | ptsIn2D = ptsIn[0,:] 98 | ptsOut2D = ptsOut[0,:] 99 | ptsOut2Dlist = [] 100 | ptsIn2Dlist = [] 101 | 102 | for i in range(0,4): 103 | ptsOut2Dlist.append([ptsOut2D[i,0], ptsOut2D[i,1]]) 104 | ptsIn2Dlist.append([ptsIn2D[i,0], ptsIn2D[i,1]]) 105 | 106 | pin = np.array(ptsIn2Dlist) + [W/2.,H/2.] 107 | pout = (np.array(ptsOut2Dlist) + [1.,1.]) * (0.5*sidelength) 108 | pin = pin.astype(np.float32) 109 | pout = pout.astype(np.float32) 110 | 111 | return pin, pout 112 | 113 | 114 | def warpMatrix(W, H, theta, phi, gamma, scale, fV): 115 | 116 | # M is to be estimated 117 | M = np.eye(4, 4) 118 | 119 | fVhalf = np.deg2rad(fV/2.) 120 | d = np.sqrt(W*W+H*H) 121 | sideLength = scale*d/np.cos(fVhalf) 122 | h = d/(2.0*np.sin(fVhalf)) 123 | n = h-(d/2.0) 124 | f = h+(d/2.0) 125 | 126 | # Translation along Z-axis by -h 127 | T = np.eye(4,4) 128 | T[2,3] = -h 129 | 130 | # Rotation matrices around x,y,z 131 | R = getRotationMatrixManual([phi, gamma, theta]) 132 | 133 | 134 | # Projection Matrix 135 | P = np.eye(4,4) 136 | P[0,0] = 1.0/np.tan(fVhalf) 137 | P[1,1] = P[0,0] 138 | P[2,2] = -(f+n)/(f-n) 139 | P[2,3] = -(2.0*f*n)/(f-n) 140 | P[3,2] = -1.0 141 | 142 | # pythonic matrix multiplication 143 | F = reduce(lambda x,y : np.matmul(x,y), [P, T, R]) 144 | 145 | # shape should be 1,4,3 for ptsIn and ptsOut since perspectiveTransform() expects data in this way. 146 | # In C++, this can be achieved by Mat ptsIn(1,4,CV_64FC3); 147 | ptsIn = np.array([[ 148 | [-W/2., H/2., 0.],[ W/2., H/2., 0.],[ W/2.,-H/2., 0.],[-W/2.,-H/2., 0.] 149 | ]]) 150 | ptsOut = np.array(np.zeros((ptsIn.shape), dtype=ptsIn.dtype)) 151 | ptsOut = cv2.perspectiveTransform(ptsIn, F) 152 | 153 | ptsInPt2f, ptsOutPt2f = getPoints_for_PerspectiveTranformEstimation(ptsIn, ptsOut, W, H, sideLength) 154 | 155 | # check float32 otherwise OpenCV throws an error 156 | assert(ptsInPt2f.dtype == np.float32) 157 | assert(ptsOutPt2f.dtype == np.float32) 158 | M33 = cv2.getPerspectiveTransform(ptsInPt2f,ptsOutPt2f) 159 | 160 | return M33, sideLength 161 | 162 | def get_flip_perspective_matrix(W, H, keys, frame_idx): 163 | perspective_flip_theta = keys.perspective_flip_theta_series[frame_idx] 164 | perspective_flip_phi = keys.perspective_flip_phi_series[frame_idx] 165 | perspective_flip_gamma = keys.perspective_flip_gamma_series[frame_idx] 166 | perspective_flip_fv = keys.perspective_flip_fv_series[frame_idx] 167 | M,sl = warpMatrix(W, H, perspective_flip_theta, perspective_flip_phi, perspective_flip_gamma, 1., perspective_flip_fv); 168 | post_trans_mat = np.float32([[1, 0, (W-sl)/2], [0, 1, (H-sl)/2]]) 169 | post_trans_mat = np.vstack([post_trans_mat, [0,0,1]]) 170 | bM = np.matmul(M, post_trans_mat) 171 | return bM 172 | 173 | def flip_3d_perspective(anim_args, prev_img_cv2, keys, frame_idx): 174 | W, H = (prev_img_cv2.shape[1], prev_img_cv2.shape[0]) 175 | return cv2.warpPerspective( 176 | prev_img_cv2, 177 | get_flip_perspective_matrix(W, H, keys, frame_idx), 178 | (W, H), 179 | borderMode=cv2.BORDER_WRAP if anim_args.border == 'wrap' else cv2.BORDER_REPLICATE 180 | ) 181 | 182 | def anim_frame_warp(prev_img_cv2, args, anim_args, keys, frame_idx, depth_model=None, depth=None, device='cuda', half_precision = False): 183 | 184 | if anim_args.use_depth_warping: 185 | if depth is None and depth_model is not None: 186 | depth = depth_model.predict(prev_img_cv2, anim_args.midas_weight, half_precision) 187 | 188 | else: 189 | depth = None 190 | 191 | if anim_args.animation_mode == '2D': 192 | prev_img = anim_frame_warp_2d(prev_img_cv2, args, anim_args, keys, frame_idx) 193 | else: # '3D' 194 | prev_img = anim_frame_warp_3d(device, prev_img_cv2, depth, anim_args, keys, frame_idx) 195 | 196 | return prev_img, depth 197 | 198 | def anim_frame_warp_2d(prev_img_cv2, args, anim_args, keys, frame_idx): 199 | angle = keys.angle_series[frame_idx] 200 | zoom = keys.zoom_series[frame_idx] 201 | translation_x = keys.translation_x_series[frame_idx] 202 | translation_y = keys.translation_y_series[frame_idx] 203 | transform_center_x = keys.transform_center_x_series[frame_idx] 204 | transform_center_y = keys.transform_center_y_series[frame_idx] 205 | center_point = (args.W * transform_center_x, args.H * transform_center_y) 206 | rot_mat = cv2.getRotationMatrix2D(center_point, angle, zoom) 207 | trans_mat = np.float32([[1, 0, translation_x], [0, 1, translation_y]]) 208 | trans_mat = np.vstack([trans_mat, [0,0,1]]) 209 | rot_mat = np.vstack([rot_mat, [0,0,1]]) 210 | if anim_args.enable_perspective_flip: 211 | bM = get_flip_perspective_matrix(args.W, args.H, keys, frame_idx) 212 | rot_mat = np.matmul(bM, rot_mat, trans_mat) 213 | else: 214 | rot_mat = np.matmul(rot_mat, trans_mat) 215 | return cv2.warpPerspective( 216 | prev_img_cv2, 217 | rot_mat, 218 | (prev_img_cv2.shape[1], prev_img_cv2.shape[0]), 219 | borderMode=cv2.BORDER_WRAP if anim_args.border == 'wrap' else cv2.BORDER_REPLICATE 220 | ) 221 | 222 | def anim_frame_warp_3d(device, prev_img_cv2, depth, anim_args, keys, frame_idx): 223 | TRANSLATION_SCALE = 1.0/200.0 # matches Disco 224 | use_parseq_through_deforumator = int(mediator_getValue("use_parseq").strip().strip('\n')) 225 | if usingDeforumation: #Should we Connect to the Deforumation websocket server to get translation values? 226 | if use_parseq_through_deforumator and int(mediator_getValue("should_use_deforumation_panning")) == 1: 227 | deforumation_translation_x = float(mediator_getValue("translation_x").strip().strip('\n')) 228 | deforumation_translation_y = float(mediator_getValue("translation_y").strip().strip('\n')) 229 | txs = deforumation_translation_x 230 | tys = deforumation_translation_y 231 | elif int(mediator_getValue("should_use_deforumation_panning")) == 1: 232 | deforumation_translation_x = float(mediator_getValue("translation_x").strip().strip('\n')) 233 | deforumation_translation_y = float(mediator_getValue("translation_y").strip().strip('\n')) 234 | txs = keys.translation_x_series[frame_idx] + deforumation_translation_x 235 | tys = keys.translation_y_series[frame_idx] + deforumation_translation_y 236 | else: 237 | txs = keys.translation_x_series[frame_idx] 238 | tys = keys.translation_y_series[frame_idx] 239 | 240 | if use_parseq_through_deforumator and int(mediator_getValue("should_use_deforumation_zoomfov")) == 1: 241 | deforumation_translation_z = float(mediator_getValue("translation_z").strip().strip('\n')) 242 | tzs = deforumation_translation_z 243 | elif int(mediator_getValue("should_use_deforumation_zoomfov")) == 1: 244 | deforumation_translation_z = float(mediator_getValue("translation_z").strip().strip('\n')) 245 | tzs = keys.translation_z_series[frame_idx] + deforumation_translation_z 246 | else: 247 | tzs = keys.translation_z_series[frame_idx] 248 | 249 | translate_xyz = [ 250 | -txs * TRANSLATION_SCALE, 251 | tys * TRANSLATION_SCALE, 252 | -tzs * TRANSLATION_SCALE 253 | ] 254 | mediator_setValue("deforum_translation_x",txs) 255 | mediator_setValue("deforum_translation_y",tys) 256 | mediator_setValue("deforum_translation_z",tzs) 257 | #mediator_setValue("translation_x",txs) 258 | #mediator_setValue("translation_y",tys) 259 | #mediator_setValue("translation_z",tzs) 260 | 261 | else: #If we are not using Deforumation, go with the values in Deforum GUI (or if we can't connect to the Deforumation server). 262 | translate_xyz = [ 263 | -keys.translation_x_series[frame_idx] * TRANSLATION_SCALE, 264 | keys.translation_y_series[frame_idx] * TRANSLATION_SCALE, 265 | -keys.translation_z_series[frame_idx] * TRANSLATION_SCALE 266 | ] 267 | 268 | 269 | if usingDeforumation: #Should we Connect to the Deforumation websocket server to get rotation values? 270 | if use_parseq_through_deforumator and int(mediator_getValue("should_use_deforumation_rotation")) == 1: 271 | deforumation_rotation_x = float(mediator_getValue("rotation_x").strip().strip('\n')) 272 | deforumation_rotation_y = float(mediator_getValue("rotation_y").strip().strip('\n')) 273 | rxs = deforumation_rotation_x 274 | rys = deforumation_rotation_y 275 | elif int(mediator_getValue("should_use_deforumation_rotation")) == 1: 276 | deforumation_rotation_x = float(mediator_getValue("rotation_x").strip().strip('\n')) 277 | deforumation_rotation_y = float(mediator_getValue("rotation_y").strip().strip('\n')) 278 | rxs = keys.rotation_3d_x_series[frame_idx] + deforumation_rotation_x 279 | rys = keys.rotation_3d_y_series[frame_idx] + deforumation_rotation_y 280 | else: 281 | rxs = keys.rotation_3d_x_series[frame_idx] 282 | rys = keys.rotation_3d_y_series[frame_idx] 283 | 284 | if use_parseq_through_deforumator and int(mediator_getValue("should_use_deforumation_tilt")) == 1: 285 | deforumation_rotation_z = float(mediator_getValue("rotation_z").strip().strip('\n')) 286 | rzs = deforumation_rotation_z 287 | elif int(mediator_getValue("should_use_deforumation_tilt")) == 1: 288 | deforumation_rotation_z = float(mediator_getValue("rotation_z").strip().strip('\n')) 289 | rzs = keys.rotation_3d_z_series[frame_idx] + deforumation_rotation_z 290 | else: 291 | rzs = keys.rotation_3d_z_series[frame_idx] 292 | 293 | rotate_xyz = [ 294 | math.radians(rxs), 295 | math.radians(rys), 296 | math.radians(rzs) 297 | ] 298 | mediator_setValue("deforum_rotation_x",rxs) 299 | mediator_setValue("deforum_rotation_y",rys) 300 | mediator_setValue("deforum_rotation_z",rzs) 301 | #mediator_setValue("rotation_x",rxs) 302 | #mediator_setValue("rotation_y",rys) 303 | #mediator_setValue("rotation_z",rzs) 304 | 305 | else: 306 | rotate_xyz = [ 307 | math.radians(keys.rotation_3d_x_series[frame_idx]), 308 | math.radians(keys.rotation_3d_y_series[frame_idx]), 309 | math.radians(keys.rotation_3d_z_series[frame_idx]) 310 | ] 311 | 312 | if anim_args.enable_perspective_flip: 313 | prev_img_cv2 = flip_3d_perspective(anim_args, prev_img_cv2, keys, frame_idx) 314 | rot_mat = p3d.euler_angles_to_matrix(torch.tensor(rotate_xyz, device=device), "XYZ").unsqueeze(0) 315 | result = transform_image_3d_switcher(device if not device.type.startswith('mps') else torch.device('cpu'), prev_img_cv2, depth, rot_mat, translate_xyz, anim_args, keys, frame_idx) 316 | torch.cuda.empty_cache() 317 | return result 318 | 319 | def transform_image_3d_switcher(device, prev_img_cv2, depth_tensor, rot_mat, translate, anim_args, keys, frame_idx): 320 | if anim_args.depth_algorithm.lower() in ['midas+adabins (old)', 'zoe+adabins (old)']: 321 | return transform_image_3d_legacy(device, prev_img_cv2, depth_tensor, rot_mat, translate, anim_args, keys, frame_idx) 322 | else: 323 | return transform_image_3d_new(device, prev_img_cv2, depth_tensor, rot_mat, translate, anim_args, keys, frame_idx) 324 | 325 | def transform_image_3d_legacy(device, prev_img_cv2, depth_tensor, rot_mat, translate, anim_args, keys, frame_idx): 326 | # adapted and optimized version of transform_image_3d from Disco Diffusion https://github.com/alembics/disco-diffusion 327 | w, h = prev_img_cv2.shape[1], prev_img_cv2.shape[0] 328 | 329 | if anim_args.aspect_ratio_use_old_formula: 330 | aspect_ratio = float(w)/float(h) 331 | else: 332 | aspect_ratio = keys.aspect_ratio_series[frame_idx] 333 | 334 | near = keys.near_series[frame_idx] 335 | far = keys.far_series[frame_idx] 336 | 337 | use_parseq_through_deforumator = int(mediator_getValue("use_parseq").strip().strip('\n')) 338 | if usingDeforumation: #Should we Connect to the Deforumation websocket server to get rotation values? 339 | if int(mediator_getValue("should_use_deforumation_zoomfov")) == 1: 340 | fov_deg = float(mediator_getValue("fov").strip().strip('\n')) 341 | mediator_setValue("deforum_fov", fov_deg) 342 | else: 343 | fov_deg = keys.fov_series[frame_idx] 344 | mediator_setValue("deforum_fov", fov_deg) 345 | #mediator_setValue("fov", fov_deg) 346 | else: #If we are not using Deforumation, go with the values in Deforum GUI (or if we can't connect to the Deforumation server). 347 | fov_deg = keys.fov_series[frame_idx] 348 | persp_cam_old = p3d.FoVPerspectiveCameras(near, far, aspect_ratio, fov=fov_deg, degrees=True, device=device) 349 | persp_cam_new = p3d.FoVPerspectiveCameras(near, far, aspect_ratio, fov=fov_deg, degrees=True, R=rot_mat, T=torch.tensor([translate]), device=device) 350 | 351 | # range of [-1,1] is important to torch grid_sample's padding handling 352 | y,x = torch.meshgrid(torch.linspace(-1.,1.,h,dtype=torch.float32,device=device),torch.linspace(-1.,1.,w,dtype=torch.float32,device=device)) 353 | if depth_tensor is None: 354 | z = torch.ones_like(x) 355 | else: 356 | z = torch.as_tensor(depth_tensor, dtype=torch.float32, device=device) 357 | xyz_old_world = torch.stack((x.flatten(), y.flatten(), z.flatten()), dim=1) 358 | 359 | xyz_old_cam_xy = persp_cam_old.get_full_projection_transform().transform_points(xyz_old_world)[:,0:2] 360 | xyz_new_cam_xy = persp_cam_new.get_full_projection_transform().transform_points(xyz_old_world)[:,0:2] 361 | 362 | offset_xy = xyz_new_cam_xy - xyz_old_cam_xy 363 | # affine_grid theta param expects a batch of 2D mats. Each is 2x3 to do rotation+translation. 364 | identity_2d_batch = torch.tensor([[1.,0.,0.],[0.,1.,0.]], device=device).unsqueeze(0) 365 | # coords_2d will have shape (N,H,W,2).. which is also what grid_sample needs. 366 | coords_2d = torch.nn.functional.affine_grid(identity_2d_batch, [1,1,h,w], align_corners=False) 367 | offset_coords_2d = coords_2d - torch.reshape(offset_xy, (h,w,2)).unsqueeze(0) 368 | 369 | image_tensor = rearrange(torch.from_numpy(prev_img_cv2.astype(np.float32)), 'h w c -> c h w').to(device) 370 | new_image = torch.nn.functional.grid_sample( 371 | image_tensor.add(1/512 - 0.0001).unsqueeze(0), 372 | offset_coords_2d, 373 | mode=anim_args.sampling_mode, 374 | padding_mode=anim_args.padding_mode, 375 | align_corners=False 376 | ) 377 | 378 | # convert back to cv2 style numpy array 379 | result = rearrange( 380 | new_image.squeeze().clamp(0,255), 381 | 'c h w -> h w c' 382 | ).cpu().numpy().astype(prev_img_cv2.dtype) 383 | return result 384 | 385 | def transform_image_3d_new(device, prev_img_cv2, depth_tensor, rot_mat, translate, anim_args, keys, frame_idx): 386 | ''' 387 | originally an adapted and optimized version of transform_image_3d from Disco Diffusion https://github.com/alembics/disco-diffusion 388 | modified by reallybigname to control various incoming tensors 389 | ''' 390 | if anim_args.depth_algorithm.lower().startswith('midas'): # 'Midas-3-Hybrid' or 'Midas-3.1-BeitLarge' 391 | depth = 1 392 | depth_factor = -1 393 | depth_offset = -2 394 | elif anim_args.depth_algorithm.lower() == "adabins": 395 | depth = 1 396 | depth_factor = 1 397 | depth_offset = 1 398 | elif anim_args.depth_algorithm.lower() == "leres": 399 | depth = 1 400 | depth_factor = 1 401 | depth_offset = 1 402 | elif anim_args.depth_algorithm.lower() == "zoe": 403 | depth = 1 404 | depth_factor = 1 405 | depth_offset = 1 406 | else: 407 | raise Exception(f"Unknown depth_algorithm passed to transform_image_3d function: {anim_args.depth_algorithm}") 408 | 409 | w, h = prev_img_cv2.shape[1], prev_img_cv2.shape[0] 410 | 411 | # depth stretching aspect ratio (has nothing to do with image dimensions - which is why the old formula was flawed) 412 | aspect_ratio = float(w)/float(h) if anim_args.aspect_ratio_use_old_formula else keys.aspect_ratio_series[frame_idx] 413 | 414 | # get projection keys 415 | near = keys.near_series[frame_idx] 416 | far = keys.far_series[frame_idx] 417 | use_parseq_through_deforumator = int(mediator_getValue("use_parseq").strip().strip('\n')) 418 | if usingDeforumation: #Should we Connect to the Deforumation websocket server to get rotation values? 419 | if int(mediator_getValue("should_use_deforumation_zoomfov")) == 1: 420 | fov_deg = float(mediator_getValue("fov").strip().strip('\n')) 421 | mediator_setValue("deforum_fov", fov_deg) 422 | else: 423 | fov_deg = keys.fov_series[frame_idx] 424 | mediator_setValue("deforum_fov", fov_deg) 425 | #mediator_setValue("fov", fov_deg) 426 | else: #If we are not using Deforumation, go with the values in Deforum GUI (or if we can't connect to the Deforumation server). 427 | fov_deg = keys.fov_series[frame_idx] 428 | 429 | # get perspective cams old (still) and new (transformed) 430 | persp_cam_old = p3d.FoVPerspectiveCameras(near, far, aspect_ratio, fov=fov_deg, degrees=True, device=device) 431 | persp_cam_new = p3d.FoVPerspectiveCameras(near, far, aspect_ratio, fov=fov_deg, degrees=True, R=rot_mat, T=torch.tensor([translate]), device=device) 432 | 433 | # make xy meshgrid - range of [-1,1] is important to torch grid_sample's padding handling 434 | y,x = torch.meshgrid(torch.linspace(-1.,1.,h,dtype=torch.float32,device=device),torch.linspace(-1.,1.,w,dtype=torch.float32,device=device)) 435 | 436 | # test tensor for validity (some are corrupted for some reason) 437 | depth_tensor_invalid = depth_tensor is None or torch.isnan(depth_tensor).any() or torch.isinf(depth_tensor).any() or depth_tensor.min() == depth_tensor.max() 438 | 439 | if depth_tensor is not None: 440 | debug_print(f"Depth_T.min: {depth_tensor.min()}, Depth_T.max: {depth_tensor.max()}") 441 | 442 | # if invalid, create flat z for this frame 443 | if depth_tensor_invalid: 444 | # if none, then 3D depth is turned off, so no warning is needed. 445 | if depth_tensor is not None: 446 | print("Depth tensor invalid. Generating a Flat depth for this frame.") 447 | # create flat depth 448 | z = torch.ones_like(x) 449 | # create z from depth tensor 450 | else: 451 | # prepare tensor between 0 and 1 with optional equalization and autocontrast 452 | depth_normalized = prepare_depth_tensor(depth_tensor) 453 | 454 | # Rescale the depth values to depth with offset (depth 2 and offset -1 would be -1 to +11) 455 | depth_final = depth_normalized * depth + depth_offset 456 | 457 | # depth factor (1 is normal. -1 is inverted) 458 | if depth_factor != 1: 459 | depth_final *= depth_factor 460 | 461 | # console reporting of depth normalization, min, max, diff 462 | # will *only* print to console if Dev mode is enabled in general settings of Deforum 463 | txt_depth_min, txt_depth_max = '{:.2f}'.format(float(depth_tensor.min())), '{:.2f}'.format(float(depth_tensor.max())) 464 | diff = '{:.2f}'.format(float(depth_tensor.max()) - float(depth_tensor.min())) 465 | console_txt = f"\033[36mDepth normalized to {depth_final.min()}/{depth_final.max()} from" 466 | debug_print(f"{console_txt} {txt_depth_min}/{txt_depth_max} diff {diff}\033[0m") 467 | 468 | # add z from depth 469 | z = torch.as_tensor(depth_final, dtype=torch.float32, device=device) 470 | 471 | # calculate offset_xy 472 | xyz_old_world = torch.stack((x.flatten(), y.flatten(), z.flatten()), dim=1) 473 | xyz_old_cam_xy = persp_cam_old.get_full_projection_transform().transform_points(xyz_old_world)[:,0:2] 474 | xyz_new_cam_xy = persp_cam_new.get_full_projection_transform().transform_points(xyz_old_world)[:,0:2] 475 | offset_xy = xyz_new_cam_xy - xyz_old_cam_xy 476 | 477 | # affine_grid theta param expects a batch of 2D mats. Each is 2x3 to do rotation+translation. 478 | identity_2d_batch = torch.tensor([[1.,0.,0.],[0.,1.,0.]], device=device).unsqueeze(0) 479 | 480 | # coords_2d will have shape (N,H,W,2).. which is also what grid_sample needs. 481 | coords_2d = torch.nn.functional.affine_grid(identity_2d_batch, [1,1,h,w], align_corners=False) 482 | offset_coords_2d = coords_2d - torch.reshape(offset_xy, (h,w,2)).unsqueeze(0) 483 | 484 | # do the hyperdimensional remap 485 | image_tensor = rearrange(torch.from_numpy(prev_img_cv2.astype(np.float32)), 'h w c -> c h w').to(device) 486 | new_image = torch.nn.functional.grid_sample( 487 | image_tensor.unsqueeze(0), # image_tensor.add(1/512 - 0.0001).unsqueeze(0), 488 | offset_coords_2d, 489 | mode=anim_args.sampling_mode, 490 | padding_mode=anim_args.padding_mode, 491 | align_corners=False 492 | ) 493 | 494 | # convert back to cv2 style numpy array 495 | result = rearrange( 496 | new_image.squeeze().clamp(0,255), 497 | 'c h w -> h w c' 498 | ).cpu().numpy().astype(prev_img_cv2.dtype) 499 | return result 500 | 501 | def prepare_depth_tensor(depth_tensor=None): 502 | # Prepares a depth tensor with normalization & equalization between 0 and 1 503 | depth_range = depth_tensor.max() - depth_tensor.min() 504 | depth_tensor = (depth_tensor - depth_tensor.min()) / depth_range 505 | depth_tensor = depth_equalization(depth_tensor=depth_tensor) 506 | return depth_tensor 507 | 508 | def depth_equalization(depth_tensor): 509 | """ 510 | Perform histogram equalization on a single-channel depth tensor. 511 | 512 | Args: 513 | depth_tensor (torch.Tensor): A 2D depth tensor (H, W). 514 | 515 | Returns: 516 | torch.Tensor: Equalized depth tensor (2D). 517 | """ 518 | 519 | # Convert the depth tensor to a NumPy array for processing 520 | depth_array = depth_tensor.cpu().numpy() 521 | 522 | # Calculate the histogram of the depth values using a specified number of bins 523 | # Increase the number of bins for higher precision depth tensors 524 | hist, bin_edges = np.histogram(depth_array, bins=1024, range=(0, 1)) 525 | 526 | # Calculate the cumulative distribution function (CDF) of the histogram 527 | cdf = hist.cumsum() 528 | 529 | # Normalize the CDF so that the maximum value is 1 530 | cdf = cdf / float(cdf[-1]) 531 | 532 | # Perform histogram equalization by mapping the original depth values to the CDF values 533 | equalized_depth_array = np.interp(depth_array, bin_edges[:-1], cdf) 534 | 535 | # Convert the equalized depth array back to a PyTorch tensor and return it 536 | equalized_depth_tensor = torch.from_numpy(equalized_depth_array).to(depth_tensor.device) 537 | 538 | return equalized_depth_tensor 539 | -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/colab_files/deforum_mediator.py: -------------------------------------------------------------------------------- 1 | import ast 2 | import asyncio 3 | import copy 4 | import time 5 | import websockets 6 | import pickle 7 | import threading 8 | import sys 9 | from pickle import HIGHEST_PROTOCOL 10 | 11 | needToUpdateMediator = False 12 | anim_args_copy = None 13 | args_copy = None 14 | async def sendAsync(value): 15 | async with websockets.connect("ws://8.tcp.ngrok.io:16089") as websocket: 16 | # await websocket.send(pickle.dumps(value)) 17 | try: 18 | await asyncio.wait_for(websocket.send(pickle.dumps(value)), timeout=10.0) 19 | message = await asyncio.wait_for(websocket.recv(), timeout=10.0) 20 | except TimeoutError: 21 | print('timeout!') 22 | if message.startswith("[\'") and message.endswith("\']"): 23 | message = ast.literal_eval(message) 24 | if len(message) == 1: 25 | message = str(message[0]) 26 | 27 | return message 28 | 29 | def mediator_set_anim_args(anim_args, args, root): 30 | global anim_args_copy 31 | global args_copy 32 | global root_copy 33 | anim_args_copy = anim_args 34 | args_copy = args 35 | root_copy = root 36 | 37 | def updateMediator(): #No validation is made that the websocket server (Mediator.py is actually up and running) 38 | print("Was ordered to update time_string") 39 | if anim_args_copy.resume_from_timestring: 40 | print("Sending Values:" + str(anim_args_copy.resume_timestring)) 41 | return_value = asyncio.run(sendAsync([1, "resume_timestring", anim_args_copy.resume_timestring])) 42 | #mediator_setValue("resume_timestring", anim_args_copy.resume_timestring) 43 | else: 44 | print("Sending Values:" + str(root_copy.timestring)) 45 | return_value = asyncio.run(sendAsync([1, "resume_timestring", root_copy.timestring])) 46 | #mediator_setValue("resume_timestring", root_copy.timestring) 47 | #OUTDIR is the same for either you resume or not. 48 | mediator_setValue("frame_outdir", args_copy.outdir) 49 | 50 | 51 | def mediator_getValue(param): 52 | global needToUpdateMediator 53 | checkerrorConnecting = True 54 | needToUpdateMediator = False 55 | while checkerrorConnecting: 56 | try: 57 | return_value = asyncio.run(sendAsync([0, param, 0])) 58 | if needToUpdateMediator: 59 | needToUpdateMediator = False 60 | updateMediator() 61 | return return_value 62 | except Exception as e: 63 | print("Deforum Mediator Error:" + str(e)) 64 | print("...while trying to get parameter ("+str(param)+")") 65 | print("The Deforumation Mediator, is probably not connected (waiting 2 seconds, before trying to reconnect...)") 66 | time.sleep(2) 67 | needToUpdateMediator = True 68 | 69 | def mediator_setValue(param, value): 70 | global needToUpdateMediator 71 | checkerrorConnecting = True 72 | needToUpdateMediator = False 73 | while checkerrorConnecting: 74 | try: 75 | return_value = asyncio.run(sendAsync([1, param, value])) 76 | if needToUpdateMediator: 77 | needToUpdateMediator = False 78 | updateMediator() 79 | return return_value 80 | except Exception as e: 81 | print("Deforum Mediator Error:" + str(e)) 82 | print("...while trying to send parameter ("+str(param)+") with value("+str(value)+")") 83 | print("The Deforumation Mediator, is probably not connected (waiting 2 seconds, before trying to reconnect...)") 84 | time.sleep(2) 85 | needToUpdateMediator = True -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/deforum-for-automatic1111-webui/scripts/deforum_helpers/animation.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 Deforum LLC 2 | # 3 | # This program is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU Affero General Public License as published by 5 | # the Free Software Foundation, version 3 of the License. 6 | # 7 | # This program is distributed in the hope that it will be useful, 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | # GNU General Public License for more details. 11 | # 12 | # You should have received a copy of the GNU Affero General Public License 13 | # along with this program. If not, see . 14 | 15 | # Contact the authors: https://deforum.github.io/ 16 | 17 | import numpy as np 18 | import cv2 19 | import py3d_tools as p3d # this is actually a file in our /src folder! 20 | from functools import reduce 21 | import math 22 | import torch 23 | from einops import rearrange 24 | from modules.shared import state, opts 25 | from .prompt import check_is_number 26 | from .general_utils import debug_print 27 | 28 | #Deforumation_mediator imports/settings 29 | from .deforum_mediator import mediator_getValue, mediator_setValue 30 | usingDeforumation = True 31 | #End settings 32 | 33 | # Webui 34 | #from modules.shared import state, opts 35 | #DEBUG_MODE = opts.data.get("deforum_debug_mode_enabled", False) 36 | 37 | def sample_from_cv2(sample: np.ndarray) -> torch.Tensor: 38 | sample = ((sample.astype(float) / 255.0) * 2) - 1 39 | sample = sample[None].transpose(0, 3, 1, 2).astype(np.float16) 40 | sample = torch.from_numpy(sample) 41 | return sample 42 | 43 | def sample_to_cv2(sample: torch.Tensor, type=np.uint8) -> np.ndarray: 44 | sample_f32 = rearrange(sample.squeeze().cpu().numpy(), "c h w -> h w c").astype(np.float32) 45 | sample_f32 = ((sample_f32 * 0.5) + 0.5).clip(0, 1) 46 | sample_int8 = (sample_f32 * 255) 47 | return sample_int8.astype(type) 48 | 49 | def construct_RotationMatrixHomogenous(rotation_angles): 50 | assert(type(rotation_angles)==list and len(rotation_angles)==3) 51 | RH = np.eye(4,4) 52 | cv2.Rodrigues(np.array(rotation_angles), RH[0:3, 0:3]) 53 | return RH 54 | 55 | # https://en.wikipedia.org/wiki/Rotation_matrix 56 | def getRotationMatrixManual(rotation_angles): 57 | 58 | rotation_angles = [np.deg2rad(x) for x in rotation_angles] 59 | 60 | phi = rotation_angles[0] # around x 61 | gamma = rotation_angles[1] # around y 62 | theta = rotation_angles[2] # around z 63 | 64 | # X rotation 65 | Rphi = np.eye(4,4) 66 | sp = np.sin(phi) 67 | cp = np.cos(phi) 68 | Rphi[1,1] = cp 69 | Rphi[2,2] = Rphi[1,1] 70 | Rphi[1,2] = -sp 71 | Rphi[2,1] = sp 72 | 73 | # Y rotation 74 | Rgamma = np.eye(4,4) 75 | sg = np.sin(gamma) 76 | cg = np.cos(gamma) 77 | Rgamma[0,0] = cg 78 | Rgamma[2,2] = Rgamma[0,0] 79 | Rgamma[0,2] = sg 80 | Rgamma[2,0] = -sg 81 | 82 | # Z rotation (in-image-plane) 83 | Rtheta = np.eye(4,4) 84 | st = np.sin(theta) 85 | ct = np.cos(theta) 86 | Rtheta[0,0] = ct 87 | Rtheta[1,1] = Rtheta[0,0] 88 | Rtheta[0,1] = -st 89 | Rtheta[1,0] = st 90 | 91 | R = reduce(lambda x,y : np.matmul(x,y), [Rphi, Rgamma, Rtheta]) 92 | 93 | return R 94 | 95 | def getPoints_for_PerspectiveTranformEstimation(ptsIn, ptsOut, W, H, sidelength): 96 | 97 | ptsIn2D = ptsIn[0,:] 98 | ptsOut2D = ptsOut[0,:] 99 | ptsOut2Dlist = [] 100 | ptsIn2Dlist = [] 101 | 102 | for i in range(0,4): 103 | ptsOut2Dlist.append([ptsOut2D[i,0], ptsOut2D[i,1]]) 104 | ptsIn2Dlist.append([ptsIn2D[i,0], ptsIn2D[i,1]]) 105 | 106 | pin = np.array(ptsIn2Dlist) + [W/2.,H/2.] 107 | pout = (np.array(ptsOut2Dlist) + [1.,1.]) * (0.5*sidelength) 108 | pin = pin.astype(np.float32) 109 | pout = pout.astype(np.float32) 110 | 111 | return pin, pout 112 | 113 | 114 | def warpMatrix(W, H, theta, phi, gamma, scale, fV): 115 | 116 | # M is to be estimated 117 | M = np.eye(4, 4) 118 | 119 | fVhalf = np.deg2rad(fV/2.) 120 | d = np.sqrt(W*W+H*H) 121 | sideLength = scale*d/np.cos(fVhalf) 122 | h = d/(2.0*np.sin(fVhalf)) 123 | n = h-(d/2.0) 124 | f = h+(d/2.0) 125 | 126 | # Translation along Z-axis by -h 127 | T = np.eye(4,4) 128 | T[2,3] = -h 129 | 130 | # Rotation matrices around x,y,z 131 | R = getRotationMatrixManual([phi, gamma, theta]) 132 | 133 | 134 | # Projection Matrix 135 | P = np.eye(4,4) 136 | P[0,0] = 1.0/np.tan(fVhalf) 137 | P[1,1] = P[0,0] 138 | P[2,2] = -(f+n)/(f-n) 139 | P[2,3] = -(2.0*f*n)/(f-n) 140 | P[3,2] = -1.0 141 | 142 | # pythonic matrix multiplication 143 | F = reduce(lambda x,y : np.matmul(x,y), [P, T, R]) 144 | 145 | # shape should be 1,4,3 for ptsIn and ptsOut since perspectiveTransform() expects data in this way. 146 | # In C++, this can be achieved by Mat ptsIn(1,4,CV_64FC3); 147 | ptsIn = np.array([[ 148 | [-W/2., H/2., 0.],[ W/2., H/2., 0.],[ W/2.,-H/2., 0.],[-W/2.,-H/2., 0.] 149 | ]]) 150 | ptsOut = np.array(np.zeros((ptsIn.shape), dtype=ptsIn.dtype)) 151 | ptsOut = cv2.perspectiveTransform(ptsIn, F) 152 | 153 | ptsInPt2f, ptsOutPt2f = getPoints_for_PerspectiveTranformEstimation(ptsIn, ptsOut, W, H, sideLength) 154 | 155 | # check float32 otherwise OpenCV throws an error 156 | assert(ptsInPt2f.dtype == np.float32) 157 | assert(ptsOutPt2f.dtype == np.float32) 158 | M33 = cv2.getPerspectiveTransform(ptsInPt2f,ptsOutPt2f) 159 | 160 | return M33, sideLength 161 | 162 | def get_flip_perspective_matrix(W, H, keys, frame_idx): 163 | perspective_flip_theta = keys.perspective_flip_theta_series[frame_idx] 164 | perspective_flip_phi = keys.perspective_flip_phi_series[frame_idx] 165 | perspective_flip_gamma = keys.perspective_flip_gamma_series[frame_idx] 166 | perspective_flip_fv = keys.perspective_flip_fv_series[frame_idx] 167 | M,sl = warpMatrix(W, H, perspective_flip_theta, perspective_flip_phi, perspective_flip_gamma, 1., perspective_flip_fv); 168 | post_trans_mat = np.float32([[1, 0, (W-sl)/2], [0, 1, (H-sl)/2]]) 169 | post_trans_mat = np.vstack([post_trans_mat, [0,0,1]]) 170 | bM = np.matmul(M, post_trans_mat) 171 | return bM 172 | 173 | def flip_3d_perspective(anim_args, prev_img_cv2, keys, frame_idx): 174 | W, H = (prev_img_cv2.shape[1], prev_img_cv2.shape[0]) 175 | return cv2.warpPerspective( 176 | prev_img_cv2, 177 | get_flip_perspective_matrix(W, H, keys, frame_idx), 178 | (W, H), 179 | borderMode=cv2.BORDER_WRAP if anim_args.border == 'wrap' else cv2.BORDER_REPLICATE 180 | ) 181 | 182 | def anim_frame_warp(prev_img_cv2, args, anim_args, keys, frame_idx, depth_model=None, depth=None, device='cuda', half_precision = False): 183 | 184 | if anim_args.use_depth_warping: 185 | if depth is None and depth_model is not None: 186 | depth = depth_model.predict(prev_img_cv2, anim_args.midas_weight, half_precision) 187 | 188 | else: 189 | depth = None 190 | 191 | if anim_args.animation_mode == '2D': 192 | prev_img = anim_frame_warp_2d(prev_img_cv2, args, anim_args, keys, frame_idx) 193 | else: # '3D' 194 | prev_img = anim_frame_warp_3d(device, prev_img_cv2, depth, anim_args, keys, frame_idx) 195 | 196 | return prev_img, depth 197 | 198 | def anim_frame_warp_2d(prev_img_cv2, args, anim_args, keys, frame_idx): 199 | angle = keys.angle_series[frame_idx] 200 | zoom = keys.zoom_series[frame_idx] 201 | translation_x = keys.translation_x_series[frame_idx] 202 | translation_y = keys.translation_y_series[frame_idx] 203 | transform_center_x = keys.transform_center_x_series[frame_idx] 204 | transform_center_y = keys.transform_center_y_series[frame_idx] 205 | center_point = (args.W * transform_center_x, args.H * transform_center_y) 206 | rot_mat = cv2.getRotationMatrix2D(center_point, angle, zoom) 207 | trans_mat = np.float32([[1, 0, translation_x], [0, 1, translation_y]]) 208 | trans_mat = np.vstack([trans_mat, [0,0,1]]) 209 | rot_mat = np.vstack([rot_mat, [0,0,1]]) 210 | if anim_args.enable_perspective_flip: 211 | bM = get_flip_perspective_matrix(args.W, args.H, keys, frame_idx) 212 | rot_mat = np.matmul(bM, rot_mat, trans_mat) 213 | else: 214 | rot_mat = np.matmul(rot_mat, trans_mat) 215 | return cv2.warpPerspective( 216 | prev_img_cv2, 217 | rot_mat, 218 | (prev_img_cv2.shape[1], prev_img_cv2.shape[0]), 219 | borderMode=cv2.BORDER_WRAP if anim_args.border == 'wrap' else cv2.BORDER_REPLICATE 220 | ) 221 | 222 | def anim_frame_warp_3d(device, prev_img_cv2, depth, anim_args, keys, frame_idx): 223 | TRANSLATION_SCALE = 1.0/200.0 # matches Disco 224 | use_parseq_through_deforumator = int(mediator_getValue("use_parseq").strip().strip('\n')) 225 | if usingDeforumation: #Should we Connect to the Deforumation websocket server to get translation values? 226 | if use_parseq_through_deforumator and int(mediator_getValue("should_use_deforumation_panning")) == 1: 227 | deforumation_translation_x = float(mediator_getValue("translation_x").strip().strip('\n')) 228 | deforumation_translation_y = float(mediator_getValue("translation_y").strip().strip('\n')) 229 | txs = deforumation_translation_x 230 | tys = deforumation_translation_y 231 | elif int(mediator_getValue("should_use_deforumation_panning")) == 1: 232 | deforumation_translation_x = float(mediator_getValue("translation_x").strip().strip('\n')) 233 | deforumation_translation_y = float(mediator_getValue("translation_y").strip().strip('\n')) 234 | txs = keys.translation_x_series[frame_idx] + deforumation_translation_x 235 | tys = keys.translation_y_series[frame_idx] + deforumation_translation_y 236 | else: 237 | txs = keys.translation_x_series[frame_idx] 238 | tys = keys.translation_y_series[frame_idx] 239 | 240 | if use_parseq_through_deforumator and int(mediator_getValue("should_use_deforumation_zoomfov")) == 1: 241 | deforumation_translation_z = float(mediator_getValue("translation_z").strip().strip('\n')) 242 | tzs = deforumation_translation_z 243 | elif int(mediator_getValue("should_use_deforumation_zoomfov")) == 1: 244 | deforumation_translation_z = float(mediator_getValue("translation_z").strip().strip('\n')) 245 | tzs = keys.translation_z_series[frame_idx] + deforumation_translation_z 246 | else: 247 | tzs = keys.translation_z_series[frame_idx] 248 | 249 | translate_xyz = [ 250 | -txs * TRANSLATION_SCALE, 251 | tys * TRANSLATION_SCALE, 252 | -tzs * TRANSLATION_SCALE 253 | ] 254 | mediator_setValue("deforum_translation_x",txs) 255 | mediator_setValue("deforum_translation_y",tys) 256 | mediator_setValue("deforum_translation_z",tzs) 257 | #mediator_setValue("translation_x",txs) 258 | #mediator_setValue("translation_y",tys) 259 | #mediator_setValue("translation_z",tzs) 260 | 261 | else: #If we are not using Deforumation, go with the values in Deforum GUI (or if we can't connect to the Deforumation server). 262 | translate_xyz = [ 263 | -keys.translation_x_series[frame_idx] * TRANSLATION_SCALE, 264 | keys.translation_y_series[frame_idx] * TRANSLATION_SCALE, 265 | -keys.translation_z_series[frame_idx] * TRANSLATION_SCALE 266 | ] 267 | 268 | 269 | if usingDeforumation: #Should we Connect to the Deforumation websocket server to get rotation values? 270 | if use_parseq_through_deforumator and int(mediator_getValue("should_use_deforumation_rotation")) == 1: 271 | deforumation_rotation_x = float(mediator_getValue("rotation_x").strip().strip('\n')) 272 | deforumation_rotation_y = float(mediator_getValue("rotation_y").strip().strip('\n')) 273 | rxs = deforumation_rotation_x 274 | rys = deforumation_rotation_y 275 | elif int(mediator_getValue("should_use_deforumation_rotation")) == 1: 276 | deforumation_rotation_x = float(mediator_getValue("rotation_x").strip().strip('\n')) 277 | deforumation_rotation_y = float(mediator_getValue("rotation_y").strip().strip('\n')) 278 | rxs = keys.rotation_3d_x_series[frame_idx] + deforumation_rotation_x 279 | rys = keys.rotation_3d_y_series[frame_idx] + deforumation_rotation_y 280 | else: 281 | rxs = keys.rotation_3d_x_series[frame_idx] 282 | rys = keys.rotation_3d_y_series[frame_idx] 283 | 284 | if use_parseq_through_deforumator and int(mediator_getValue("should_use_deforumation_tilt")) == 1: 285 | deforumation_rotation_z = float(mediator_getValue("rotation_z").strip().strip('\n')) 286 | rzs = deforumation_rotation_z 287 | elif int(mediator_getValue("should_use_deforumation_tilt")) == 1: 288 | deforumation_rotation_z = float(mediator_getValue("rotation_z").strip().strip('\n')) 289 | rzs = keys.rotation_3d_z_series[frame_idx] + deforumation_rotation_z 290 | else: 291 | rzs = keys.rotation_3d_z_series[frame_idx] 292 | 293 | rotate_xyz = [ 294 | math.radians(rxs), 295 | math.radians(rys), 296 | math.radians(rzs) 297 | ] 298 | mediator_setValue("deforum_rotation_x",rxs) 299 | mediator_setValue("deforum_rotation_y",rys) 300 | mediator_setValue("deforum_rotation_z",rzs) 301 | #mediator_setValue("rotation_x",rxs) 302 | #mediator_setValue("rotation_y",rys) 303 | #mediator_setValue("rotation_z",rzs) 304 | 305 | else: 306 | rotate_xyz = [ 307 | math.radians(keys.rotation_3d_x_series[frame_idx]), 308 | math.radians(keys.rotation_3d_y_series[frame_idx]), 309 | math.radians(keys.rotation_3d_z_series[frame_idx]) 310 | ] 311 | 312 | if anim_args.enable_perspective_flip: 313 | prev_img_cv2 = flip_3d_perspective(anim_args, prev_img_cv2, keys, frame_idx) 314 | rot_mat = p3d.euler_angles_to_matrix(torch.tensor(rotate_xyz, device=device), "XYZ").unsqueeze(0) 315 | result = transform_image_3d_switcher(device if not device.type.startswith('mps') else torch.device('cpu'), prev_img_cv2, depth, rot_mat, translate_xyz, anim_args, keys, frame_idx) 316 | torch.cuda.empty_cache() 317 | return result 318 | 319 | def transform_image_3d_switcher(device, prev_img_cv2, depth_tensor, rot_mat, translate, anim_args, keys, frame_idx): 320 | if anim_args.depth_algorithm.lower() in ['midas+adabins (old)', 'zoe+adabins (old)']: 321 | return transform_image_3d_legacy(device, prev_img_cv2, depth_tensor, rot_mat, translate, anim_args, keys, frame_idx) 322 | else: 323 | return transform_image_3d_new(device, prev_img_cv2, depth_tensor, rot_mat, translate, anim_args, keys, frame_idx) 324 | 325 | def transform_image_3d_legacy(device, prev_img_cv2, depth_tensor, rot_mat, translate, anim_args, keys, frame_idx): 326 | # adapted and optimized version of transform_image_3d from Disco Diffusion https://github.com/alembics/disco-diffusion 327 | w, h = prev_img_cv2.shape[1], prev_img_cv2.shape[0] 328 | 329 | if anim_args.aspect_ratio_use_old_formula: 330 | aspect_ratio = float(w)/float(h) 331 | else: 332 | aspect_ratio = keys.aspect_ratio_series[frame_idx] 333 | 334 | near = keys.near_series[frame_idx] 335 | far = keys.far_series[frame_idx] 336 | 337 | use_parseq_through_deforumator = int(mediator_getValue("use_parseq").strip().strip('\n')) 338 | if usingDeforumation: #Should we Connect to the Deforumation websocket server to get rotation values? 339 | if int(mediator_getValue("should_use_deforumation_zoomfov")) == 1: 340 | fov_deg = float(mediator_getValue("fov").strip().strip('\n')) 341 | mediator_setValue("deforum_fov", fov_deg) 342 | else: 343 | fov_deg = keys.fov_series[frame_idx] 344 | mediator_setValue("deforum_fov", fov_deg) 345 | #mediator_setValue("fov", fov_deg) 346 | else: #If we are not using Deforumation, go with the values in Deforum GUI (or if we can't connect to the Deforumation server). 347 | fov_deg = keys.fov_series[frame_idx] 348 | persp_cam_old = p3d.FoVPerspectiveCameras(near, far, aspect_ratio, fov=fov_deg, degrees=True, device=device) 349 | persp_cam_new = p3d.FoVPerspectiveCameras(near, far, aspect_ratio, fov=fov_deg, degrees=True, R=rot_mat, T=torch.tensor([translate]), device=device) 350 | 351 | # range of [-1,1] is important to torch grid_sample's padding handling 352 | y,x = torch.meshgrid(torch.linspace(-1.,1.,h,dtype=torch.float32,device=device),torch.linspace(-1.,1.,w,dtype=torch.float32,device=device)) 353 | if depth_tensor is None: 354 | z = torch.ones_like(x) 355 | else: 356 | z = torch.as_tensor(depth_tensor, dtype=torch.float32, device=device) 357 | xyz_old_world = torch.stack((x.flatten(), y.flatten(), z.flatten()), dim=1) 358 | 359 | xyz_old_cam_xy = persp_cam_old.get_full_projection_transform().transform_points(xyz_old_world)[:,0:2] 360 | xyz_new_cam_xy = persp_cam_new.get_full_projection_transform().transform_points(xyz_old_world)[:,0:2] 361 | 362 | offset_xy = xyz_new_cam_xy - xyz_old_cam_xy 363 | # affine_grid theta param expects a batch of 2D mats. Each is 2x3 to do rotation+translation. 364 | identity_2d_batch = torch.tensor([[1.,0.,0.],[0.,1.,0.]], device=device).unsqueeze(0) 365 | # coords_2d will have shape (N,H,W,2).. which is also what grid_sample needs. 366 | coords_2d = torch.nn.functional.affine_grid(identity_2d_batch, [1,1,h,w], align_corners=False) 367 | offset_coords_2d = coords_2d - torch.reshape(offset_xy, (h,w,2)).unsqueeze(0) 368 | 369 | image_tensor = rearrange(torch.from_numpy(prev_img_cv2.astype(np.float32)), 'h w c -> c h w').to(device) 370 | new_image = torch.nn.functional.grid_sample( 371 | image_tensor.add(1/512 - 0.0001).unsqueeze(0), 372 | offset_coords_2d, 373 | mode=anim_args.sampling_mode, 374 | padding_mode=anim_args.padding_mode, 375 | align_corners=False 376 | ) 377 | 378 | # convert back to cv2 style numpy array 379 | result = rearrange( 380 | new_image.squeeze().clamp(0,255), 381 | 'c h w -> h w c' 382 | ).cpu().numpy().astype(prev_img_cv2.dtype) 383 | return result 384 | 385 | def transform_image_3d_new(device, prev_img_cv2, depth_tensor, rot_mat, translate, anim_args, keys, frame_idx): 386 | ''' 387 | originally an adapted and optimized version of transform_image_3d from Disco Diffusion https://github.com/alembics/disco-diffusion 388 | modified by reallybigname to control various incoming tensors 389 | ''' 390 | if anim_args.depth_algorithm.lower().startswith('midas'): # 'Midas-3-Hybrid' or 'Midas-3.1-BeitLarge' 391 | depth = 1 392 | depth_factor = -1 393 | depth_offset = -2 394 | elif anim_args.depth_algorithm.lower() == "adabins": 395 | depth = 1 396 | depth_factor = 1 397 | depth_offset = 1 398 | elif anim_args.depth_algorithm.lower() == "leres": 399 | depth = 1 400 | depth_factor = 1 401 | depth_offset = 1 402 | elif anim_args.depth_algorithm.lower() == "zoe": 403 | depth = 1 404 | depth_factor = 1 405 | depth_offset = 1 406 | else: 407 | raise Exception(f"Unknown depth_algorithm passed to transform_image_3d function: {anim_args.depth_algorithm}") 408 | 409 | w, h = prev_img_cv2.shape[1], prev_img_cv2.shape[0] 410 | 411 | # depth stretching aspect ratio (has nothing to do with image dimensions - which is why the old formula was flawed) 412 | aspect_ratio = float(w)/float(h) if anim_args.aspect_ratio_use_old_formula else keys.aspect_ratio_series[frame_idx] 413 | 414 | # get projection keys 415 | near = keys.near_series[frame_idx] 416 | far = keys.far_series[frame_idx] 417 | use_parseq_through_deforumator = int(mediator_getValue("use_parseq").strip().strip('\n')) 418 | if usingDeforumation: #Should we Connect to the Deforumation websocket server to get rotation values? 419 | if int(mediator_getValue("should_use_deforumation_zoomfov")) == 1: 420 | fov_deg = float(mediator_getValue("fov").strip().strip('\n')) 421 | mediator_setValue("deforum_fov", fov_deg) 422 | else: 423 | fov_deg = keys.fov_series[frame_idx] 424 | mediator_setValue("deforum_fov", fov_deg) 425 | #mediator_setValue("fov", fov_deg) 426 | else: #If we are not using Deforumation, go with the values in Deforum GUI (or if we can't connect to the Deforumation server). 427 | fov_deg = keys.fov_series[frame_idx] 428 | 429 | # get perspective cams old (still) and new (transformed) 430 | persp_cam_old = p3d.FoVPerspectiveCameras(near, far, aspect_ratio, fov=fov_deg, degrees=True, device=device) 431 | persp_cam_new = p3d.FoVPerspectiveCameras(near, far, aspect_ratio, fov=fov_deg, degrees=True, R=rot_mat, T=torch.tensor([translate]), device=device) 432 | 433 | # make xy meshgrid - range of [-1,1] is important to torch grid_sample's padding handling 434 | y,x = torch.meshgrid(torch.linspace(-1.,1.,h,dtype=torch.float32,device=device),torch.linspace(-1.,1.,w,dtype=torch.float32,device=device)) 435 | 436 | # test tensor for validity (some are corrupted for some reason) 437 | depth_tensor_invalid = depth_tensor is None or torch.isnan(depth_tensor).any() or torch.isinf(depth_tensor).any() or depth_tensor.min() == depth_tensor.max() 438 | 439 | if depth_tensor is not None: 440 | debug_print(f"Depth_T.min: {depth_tensor.min()}, Depth_T.max: {depth_tensor.max()}") 441 | 442 | # if invalid, create flat z for this frame 443 | if depth_tensor_invalid: 444 | # if none, then 3D depth is turned off, so no warning is needed. 445 | if depth_tensor is not None: 446 | print("Depth tensor invalid. Generating a Flat depth for this frame.") 447 | # create flat depth 448 | z = torch.ones_like(x) 449 | # create z from depth tensor 450 | else: 451 | # prepare tensor between 0 and 1 with optional equalization and autocontrast 452 | depth_normalized = prepare_depth_tensor(depth_tensor) 453 | 454 | # Rescale the depth values to depth with offset (depth 2 and offset -1 would be -1 to +11) 455 | depth_final = depth_normalized * depth + depth_offset 456 | 457 | # depth factor (1 is normal. -1 is inverted) 458 | if depth_factor != 1: 459 | depth_final *= depth_factor 460 | 461 | # console reporting of depth normalization, min, max, diff 462 | # will *only* print to console if Dev mode is enabled in general settings of Deforum 463 | txt_depth_min, txt_depth_max = '{:.2f}'.format(float(depth_tensor.min())), '{:.2f}'.format(float(depth_tensor.max())) 464 | diff = '{:.2f}'.format(float(depth_tensor.max()) - float(depth_tensor.min())) 465 | console_txt = f"\033[36mDepth normalized to {depth_final.min()}/{depth_final.max()} from" 466 | debug_print(f"{console_txt} {txt_depth_min}/{txt_depth_max} diff {diff}\033[0m") 467 | 468 | # add z from depth 469 | z = torch.as_tensor(depth_final, dtype=torch.float32, device=device) 470 | 471 | # calculate offset_xy 472 | xyz_old_world = torch.stack((x.flatten(), y.flatten(), z.flatten()), dim=1) 473 | xyz_old_cam_xy = persp_cam_old.get_full_projection_transform().transform_points(xyz_old_world)[:,0:2] 474 | xyz_new_cam_xy = persp_cam_new.get_full_projection_transform().transform_points(xyz_old_world)[:,0:2] 475 | offset_xy = xyz_new_cam_xy - xyz_old_cam_xy 476 | 477 | # affine_grid theta param expects a batch of 2D mats. Each is 2x3 to do rotation+translation. 478 | identity_2d_batch = torch.tensor([[1.,0.,0.],[0.,1.,0.]], device=device).unsqueeze(0) 479 | 480 | # coords_2d will have shape (N,H,W,2).. which is also what grid_sample needs. 481 | coords_2d = torch.nn.functional.affine_grid(identity_2d_batch, [1,1,h,w], align_corners=False) 482 | offset_coords_2d = coords_2d - torch.reshape(offset_xy, (h,w,2)).unsqueeze(0) 483 | 484 | # do the hyperdimensional remap 485 | image_tensor = rearrange(torch.from_numpy(prev_img_cv2.astype(np.float32)), 'h w c -> c h w').to(device) 486 | new_image = torch.nn.functional.grid_sample( 487 | image_tensor.unsqueeze(0), # image_tensor.add(1/512 - 0.0001).unsqueeze(0), 488 | offset_coords_2d, 489 | mode=anim_args.sampling_mode, 490 | padding_mode=anim_args.padding_mode, 491 | align_corners=False 492 | ) 493 | 494 | # convert back to cv2 style numpy array 495 | result = rearrange( 496 | new_image.squeeze().clamp(0,255), 497 | 'c h w -> h w c' 498 | ).cpu().numpy().astype(prev_img_cv2.dtype) 499 | return result 500 | 501 | def prepare_depth_tensor(depth_tensor=None): 502 | # Prepares a depth tensor with normalization & equalization between 0 and 1 503 | depth_range = depth_tensor.max() - depth_tensor.min() 504 | depth_tensor = (depth_tensor - depth_tensor.min()) / depth_range 505 | depth_tensor = depth_equalization(depth_tensor=depth_tensor) 506 | return depth_tensor 507 | 508 | def depth_equalization(depth_tensor): 509 | """ 510 | Perform histogram equalization on a single-channel depth tensor. 511 | 512 | Args: 513 | depth_tensor (torch.Tensor): A 2D depth tensor (H, W). 514 | 515 | Returns: 516 | torch.Tensor: Equalized depth tensor (2D). 517 | """ 518 | 519 | # Convert the depth tensor to a NumPy array for processing 520 | depth_array = depth_tensor.cpu().numpy() 521 | 522 | # Calculate the histogram of the depth values using a specified number of bins 523 | # Increase the number of bins for higher precision depth tensors 524 | hist, bin_edges = np.histogram(depth_array, bins=1024, range=(0, 1)) 525 | 526 | # Calculate the cumulative distribution function (CDF) of the histogram 527 | cdf = hist.cumsum() 528 | 529 | # Normalize the CDF so that the maximum value is 1 530 | cdf = cdf / float(cdf[-1]) 531 | 532 | # Perform histogram equalization by mapping the original depth values to the CDF values 533 | equalized_depth_array = np.interp(depth_array, bin_edges[:-1], cdf) 534 | 535 | # Convert the equalized depth array back to a PyTorch tensor and return it 536 | equalized_depth_tensor = torch.from_numpy(equalized_depth_array).to(depth_tensor.device) 537 | 538 | return equalized_depth_tensor 539 | -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/deforum-for-automatic1111-webui/scripts/deforum_helpers/deforum_mediator.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import websockets 3 | import pickle 4 | import time 5 | import ast 6 | needToUpdateMediator = False 7 | anim_args_copy = None 8 | args_copy = None 9 | root_copy = None 10 | async def sendAsync(value): 11 | async with websockets.connect("ws://localhost:8765") as websocket: 12 | # await websocket.send(pickle.dumps(value)) 13 | try: 14 | await asyncio.wait_for(websocket.send(pickle.dumps(value)), timeout=10.0) 15 | message = await asyncio.wait_for(websocket.recv(), timeout=10.0) 16 | except TimeoutError: 17 | print('timeout!') 18 | if message.startswith("[\'") and message.endswith("\']"): 19 | message = ast.literal_eval(message) 20 | if len(message) == 1: 21 | message = str(message[0]) 22 | 23 | return message 24 | 25 | def mediator_set_anim_args(anim_args, args, root): 26 | global anim_args_copy 27 | global args_copy 28 | global root_copy 29 | anim_args_copy = anim_args 30 | args_copy = args 31 | root_copy = root 32 | 33 | def updateMediator(): #No validation is made that the websocket server (Mediator.py is actually up and running) 34 | print("Was ordered to update time_string") 35 | if anim_args_copy.resume_from_timestring: 36 | print("Sending Values:" + str(anim_args_copy.resume_timestring)) 37 | return_value = asyncio.run(sendAsync([1, "resume_timestring", anim_args_copy.resume_timestring])) 38 | #mediator_setValue("resume_timestring", anim_args_copy.resume_timestring) 39 | else: 40 | print("Sending Values:" + str(root_copy.timestring)) 41 | return_value = asyncio.run(sendAsync([1, "resume_timestring", root_copy.timestring])) 42 | #mediator_setValue("resume_timestring", root_copy.timestring) 43 | #OUTDIR is the same for either you resume or not. 44 | mediator_setValue("frame_outdir", args_copy.outdir) 45 | 46 | 47 | def mediator_getValue(param): 48 | global needToUpdateMediator 49 | checkerrorConnecting = True 50 | needToUpdateMediator = False 51 | while checkerrorConnecting: 52 | try: 53 | return_value = asyncio.run(sendAsync([0, param, 0])) 54 | if needToUpdateMediator: 55 | needToUpdateMediator = False 56 | updateMediator() 57 | return return_value 58 | except Exception as e: 59 | print("Deforum Mediator Error:" + str(e)) 60 | print("...while trying to get parameter ("+str(param)+")") 61 | print("The Deforumation Mediator, is probably not connected (waiting 2 seconds, before trying to reconnect...)") 62 | time.sleep(2) 63 | needToUpdateMediator = True 64 | 65 | def mediator_setValue(param, value): 66 | global needToUpdateMediator 67 | checkerrorConnecting = True 68 | needToUpdateMediator = False 69 | while checkerrorConnecting: 70 | try: 71 | return_value = asyncio.run(sendAsync([1, param, value])) 72 | if needToUpdateMediator: 73 | needToUpdateMediator = False 74 | updateMediator() 75 | return return_value 76 | except Exception as e: 77 | print("Deforum Mediator Error:" + str(e)) 78 | print("...while trying to send parameter ("+str(param)+") with value("+str(value)+")") 79 | print("The Deforumation Mediator, is probably not connected (waiting 2 seconds, before trying to reconnect...)") 80 | time.sleep(2) 81 | needToUpdateMediator = True -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/deforum-for-automatic1111-webui/scripts/deforum_helpers/deforum_mediator_named_pipes/deforum_mediator.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import websockets 3 | import pickle 4 | import time 5 | import win32pipe, win32file, pywintypes 6 | import ast 7 | 8 | needToUpdateMediator = False 9 | anim_args_copy = None 10 | args_copy = None 11 | root_copy = None 12 | exception_in_a_row = 0 13 | #async def sendAsync(value): 14 | # handle = win32file.CreateFile('\\\\.\\pipe\\Deforum', win32file.GENERIC_READ | win32file.GENERIC_WRITE, 0, None, 15 | # win32file.OPEN_EXISTING, 0, None) 16 | # res = win32pipe.SetNamedPipeHandleState(handle, win32pipe.PIPE_READMODE_MESSAGE, None, None) 17 | # bytesToSend = pickle.dumps(value) 18 | # win32file.WriteFile(handle, bytesToSend) 19 | # message = win32file.ReadFile(handle, 64 * 1024) 20 | # 21 | # 22 | # win32file.CloseHandle(handle) 23 | # return message[1].decode() 24 | 25 | async def sendAsync(value): 26 | bufSize = 64 * 1024 27 | handle = win32file.CreateFile('\\\\.\\pipe\\Deforum', win32file.GENERIC_READ | win32file.GENERIC_WRITE, 0, None,win32file.OPEN_EXISTING, 0, None) 28 | res = win32pipe.SetNamedPipeHandleState(handle, win32pipe.PIPE_READMODE_MESSAGE, None, None) 29 | bytesToSend = pickle.dumps(value) 30 | win32file.WriteFile(handle, bytesToSend) 31 | result, data = win32file.ReadFile(handle, bufSize) 32 | message = data 33 | while len(data) == bufSize: 34 | print("More data has to be read (normal pipe async):"+ str(len(data))) 35 | result, data = win32file.ReadFile(handle, bufSize) 36 | message += data 37 | 38 | win32file.CloseHandle(handle) 39 | 40 | message = message.decode() 41 | if message.startswith("[\'") and message.endswith("\']"): 42 | message = ast.literal_eval(message) 43 | if len(message) == 1: 44 | message = str(message[0]) 45 | return message 46 | 47 | def mediator_set_anim_args(anim_args, args, root): 48 | global anim_args_copy 49 | global args_copy 50 | global root_copy 51 | anim_args_copy = anim_args 52 | args_copy = args 53 | root_copy = root 54 | 55 | def updateMediator(): #No validation is made that the websocket server (Mediator.py is actually up and running) 56 | print("Was ordered to update time_string") 57 | if anim_args_copy.resume_from_timestring: 58 | print("Sending Values:" + str(anim_args_copy.resume_timestring)) 59 | return_value = asyncio.run(sendAsync([1, "resume_timestring", anim_args_copy.resume_timestring])) 60 | #mediator_setValue("resume_timestring", anim_args_copy.resume_timestring) 61 | else: 62 | print("Sending Values:" + str(root_copy.timestring)) 63 | return_value = asyncio.run(sendAsync([1, "resume_timestring", root_copy.timestring])) 64 | #mediator_setValue("resume_timestring", root_copy.timestring) 65 | #OUTDIR is the same for either you resume or not. 66 | mediator_setValue("frame_outdir", args_copy.outdir) 67 | 68 | 69 | def mediator_getValue(param): 70 | global needToUpdateMediator 71 | global exception_in_a_row 72 | checkerrorConnecting = True 73 | needToUpdateMediator = False 74 | exception_in_a_row = 0 75 | while checkerrorConnecting: 76 | try: 77 | return_value = asyncio.run(sendAsync([0, param, 0])) 78 | if needToUpdateMediator: 79 | needToUpdateMediator = False 80 | updateMediator() 81 | return return_value 82 | except Exception as e: 83 | exception_in_a_row += 1 84 | if exception_in_a_row > 20: 85 | print("Deforum Mediator Error:" + str(e)) 86 | print("...while trying to send parameter ("+str(param)+")") 87 | print("The Deforumation Mediator, is probably not connected (waiting 1.0 seconds, before trying to reconnect...)") 88 | needToUpdateMediator = True 89 | exception_in_a_row = 0 90 | time.sleep(0.05) 91 | 92 | def mediator_setValue(param, value): 93 | global needToUpdateMediator 94 | global exception_in_a_row 95 | checkerrorConnecting = True 96 | needToUpdateMediator = False 97 | exception_in_a_row = 0 98 | while checkerrorConnecting: 99 | try: 100 | return_value = asyncio.run(sendAsync([1, param, value])) 101 | if needToUpdateMediator: 102 | needToUpdateMediator = False 103 | updateMediator() 104 | return return_value 105 | except Exception as e: 106 | exception_in_a_row += 1 107 | if exception_in_a_row > 20: 108 | print("Deforum Mediator Error:" + str(e)) 109 | print("...while trying to send parameter ("+str(param)+") with value("+str(value)+")") 110 | print("The Deforumation Mediator, is probably not connected (waiting 1.0 seconds, before trying to reconnect...)") 111 | needToUpdateMediator = True 112 | exception_in_a_row = 0 113 | time.sleep(0.05) 114 | -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/deforum_settings_keys.txt: -------------------------------------------------------------------------------- 1 | pan_left_key = 65 2 | pan_right_key = 68 3 | pan_up_key = 87 4 | pan_down_key = 83 5 | zoom_up_key = 315 6 | zoom_down_key = 317 -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/deforumation_settings_motions.txt: -------------------------------------------------------------------------------- 1 | #Usage 2 | #, , , , , , 3 | Close Rotation Right, ./motion_images/close_rotation_right.gif, -1 ,[ 1.0, 0.0, 0.20, -0.20, 0.0, 0.0] 4 | Close Rotation Left, ./motion_images/close_rotation_left.gif, -1 ,[-1.0, 0.0, 0.20, 0.20, 0.0, 0.0] 5 | Medium Rotation Right, ./motion_images/medium_rotation_right.gif, -1 ,[ 1.0, 0.0, 0.15, -0.20, 0.0, 0.0] 6 | Medium Rotation Left, ./motion_images/medium_rotation_left.gif, -1 ,[-1.0, 0.0, 0.15, 0.20, 0.0, 0.0] 7 | Far Rotation Right, ./motion_images/far_rotation_right.gif, -1 ,[ 1.0, 0.0, 0.12, -0.20, 0.0, 0.0] 8 | Far Rotation Left, ./motion_images/far_rotation_left.gif, -1 ,[-1.0, 0.0, 0.12, 0.20, 0.0, 0.0] 9 | Far Zoom In (30 FPS), ./motion_images/Far_Zoom_In_(30 FPS).gif ,30 ,[0.0,0.0,0.0,0.0,0.0,0.0]:[0.0,0.0,0.0,0.0,0.0,0.0]:[0.0,0.0,0.0,0.0,0.0,0.0]:[0.0,0.0,0.0,0.0,0.0,0.0]:[0.0,0.0,0.0,0.0,0.0,0.0]:[0.0,0.0,0.002152434850243521,0.0,0.0,0.0]:[0.0,0.0,0.002152434850243521,0.0,0.0,0.0]:[0.0,0.0,0.008673491119354693,0.0,0.0,0.0]:[0.0,0.0,0.019657081148187813,0.0,0.0,0.0]:[0.0,0.0,0.035194089819685935,0.0,0.0,0.0]:[0.0,0.0,0.035194089819685935,0.0,0.0,0.0]:[0.0,0.0,0.05537133562108135,0.0,0.0,0.0]:[0.0,0.0,0.08027038594162665,0.0,0.0,0.0]:[0.0,0.0,0.10996621612791437,0.0,0.0,0.0]:[0.0,0.0,0.10996621612791437,0.0,0.0,0.0]:[0.0,0.0,0.14452570356038189,0.0,0.0,0.0]:[0.0,0.0,0.18400595069712533,0.0,0.0,0.0]:[0.0,0.0,0.22845243487444658,0.0,0.0,0.0]:[0.0,0.0,0.22845243487444658,0.0,0.0,0.0]:[0.0,0.0,0.2778969878680786,0.0,0.0,0.0]:[0.0,0.0,0.3323556150022034,0.0,0.0,0.0]:[0.0,0.0,0.3323556150022034,0.0,0.0,0.0]:[0.0,0.0,0.3918261720992806,0.0,0.0,0.0]:[0.0,0.0,0.45628592886651376,0.0,0.0,0.0]:[0.0,0.0,0.5256890593625918,0.0,0.0,0.0]:[0.0,0.0,0.5999641137498646,0.0,0.0,0.0]:[0.0,0.0,0.5999641137498646,0.0,0.0,0.0]:[0.0,0.0,0.679011540145742,0.0,0.0,0.0]:[0.0,0.0,0.7627013402906223,0.0,0.0,0.0]:[0.0,0.0,0.8508709568775347,0.0,0.0,0.0]:[0.0,0.0,0.8508709568775347,0.0,0.0,0.0]:[0.0,0.0,0.9433235023521878,0.0,0.0,0.0]:[0.0,0.0,1.0398264471343934,0.0,0.0,0.0]:[0.0,0.0,1.1401108877231563,0.0,0.0,0.0]:[0.0,0.0,1.2438715102539868,0.0,0.0,0.0]:[0.0,0.0,1.2438715102539868,0.0,0.0,0.0]:[0.0,0.0,1.350767351297421,0.0,0.0,0.0]:[0.0,0.0,1.4604234341381723,0.0,0.0,0.0]:[0.0,0.0,1.5724333254719713,0.0,0.0,0.0]:[0.0,0.0,1.6863626155638989,0.0,0.0,0.0]:[0.0,0.0,1.8017532768452655,0.0,0.0,0.0]:[0.0,0.0,1.9181288052745118,0.0,0.0,0.0]:[0.0,0.0,2.035,0.0,0.0,0.0]:[0.0,0.0,2.1518711947254894,0.0,0.0,0.0]:[0.0,0.0,2.1518711947254894,0.0,0.0,0.0]:[0.0,0.0,2.2682467231547343,0.0,0.0,0.0]:[0.0,0.0,2.3836373844361027,0.0,0.0,0.0]:[0.0,0.0,2.497566674528029,0.0,0.0,0.0]:[0.0,0.0,2.6095765658618286,0.0,0.0,0.0]:[0.0,0.0,2.6095765658618286,0.0,0.0,0.0]:[0.0,0.0,2.7192326487025786,0.0,0.0,0.0]:[0.0,0.0,2.8261284897460137,0.0,0.0,0.0]:[0.0,0.0,2.8261284897460137,0.0,0.0,0.0]:[0.0,0.0,2.9298891122768445,0.0,0.0,0.0]:[0.0,0.0,3.030173552865608,0.0,0.0,0.0]:[0.0,0.0,3.1266764976478134,0.0,0.0,0.0]:[0.0,0.0,3.2191290431224653,0.0,0.0,0.0]:[0.0,0.0,3.2191290431224653,0.0,0.0,0.0]:[0.0,0.0,3.307298659709378,0.0,0.0,0.0]:[0.0,0.0,3.3909884598542583,0.0,0.0,0.0]:[0.0,0.0,3.470035886250136,0.0,0.0,0.0]:[0.0,0.0,3.470035886250136,0.0,0.0,0.0]:[0.0,0.0,3.5443109406374087,0.0,0.0,0.0]:[0.0,0.0,3.613714071133487,0.0,0.0,0.0]:[0.0,0.0,3.67817382790072,0.0,0.0,0.0]:[0.0,0.0,3.67817382790072,0.0,0.0,0.0]:[0.0,0.0,3.7376443849977976,0.0,0.0,0.0]:[0.0,0.0,3.792103012131922,0.0,0.0,0.0]:[0.0,0.0,3.8415475651255533,0.0,0.0,0.0]:[0.0,0.0,3.885994049302875,0.0,0.0,0.0]:[0.0,0.0,3.885994049302875,0.0,0.0,0.0]:[0.0,0.0,3.9254742964396185,0.0,0.0,0.0]:[0.0,0.0,3.9600337838720856,0.0,0.0,0.0]:[0.0,0.0,3.9600337838720856,0.0,0.0,0.0]:[0.0,0.0,3.989729614058374,0.0,0.0,0.0]:[0.0,0.0,4.014628664378919,0.0,0.0,0.0]:[0.0,0.0,4.034805910180314,0.0,0.0,0.0]:[0.0,0.0,4.050342918851812,0.0,0.0,0.0]:[0.0,0.0,4.050342918851812,0.0,0.0,0.0]:[0.0,0.0,4.061326508880645,0.0,0.0,0.0]:[0.0,0.0,4.067847565149757,0.0,0.0,0.0]:[0.0,0.0,4.07,0.0,0.0,0.0]:[0.0,0.0,4.07,0.0,0.0,0.0]:[0.0,0.0,4.07,0.0,0.0,0.0]:[0.0,0.0,4.07,0.0,0.0,0.0]:[0.0,0.0,4.07,0.0,0.0,0.0]:[0.0,0.0,4.07,0.0,0.0,0.0]:[0.0,0.0,4.07,0.0,0.0,0.0]:[0.0,0.0,4.07,0.0,0.0,0.0]:[0.0,0.0,4.07,0.0,0.0,0.0]:[0.0,0.0,4.07,0.0,0.0,0.0]:[0.0,0.0,4.07,0.0,0.0,0.0]:[0.0,0.0,4.07,0.0,0.0,0.0]:[0.0,0.0,4.07,0.0,0.0,0.0]:[0.0,0.0,4.07,0.0,0.0,0.0]:[0.0,0.0,4.07,0.0,0.0,0.0]:[0.0,0.0,4.07,0.0,0.0,0.0]:[0.0,0.0,4.07,0.0,0.0,0.0]:[0.0,0.0,4.067847565149757,0.0,0.0,0.0]:[0.0,0.0,4.061326508880645,0.0,0.0,0.0]:[0.0,0.0,4.050342918851812,0.0,0.0,0.0]:[0.0,0.0,4.050342918851812,0.0,0.0,0.0]:[0.0,0.0,4.034805910180315,0.0,0.0,0.0]:[0.0,0.0,4.014628664378919,0.0,0.0,0.0]:[0.0,0.0,3.9897296140583736,0.0,0.0,0.0]:[0.0,0.0,3.9897296140583736,0.0,0.0,0.0]:[0.0,0.0,3.960033783872086,0.0,0.0,0.0]:[0.0,0.0,3.9254742964396185,0.0,0.0,0.0]:[0.0,0.0,3.885994049302875,0.0,0.0,0.0]:[0.0,0.0,3.8415475651255537,0.0,0.0,0.0]:[0.0,0.0,3.7921030121319217,0.0,0.0,0.0]:[0.0,0.0,3.7376443849977967,0.0,0.0,0.0]:[0.0,0.0,3.6781738279007197,0.0,0.0,0.0]:[0.0,0.0,3.6137140711334865,0.0,0.0,0.0]:[0.0,0.0,3.5443109406374083,0.0,0.0,0.0]:[0.0,0.0,3.4700358862501357,0.0,0.0,0.0]:[0.0,0.0,3.3909884598542583,0.0,0.0,0.0]:[0.0,0.0,3.307298659709378,0.0,0.0,0.0]:[0.0,0.0,3.307298659709378,0.0,0.0,0.0]:[0.0,0.0,3.2191290431224657,0.0,0.0,0.0]:[0.0,0.0,3.1266764976478125,0.0,0.0,0.0]:[0.0,0.0,3.030173552865607,0.0,0.0,0.0]:[0.0,0.0,2.929889112276844,0.0,0.0,0.0]:[0.0,0.0,2.8261284897460133,0.0,0.0,0.0]:[0.0,0.0,2.7192326487025795,0.0,0.0,0.0]:[0.0,0.0,2.609576565861828,0.0,0.0,0.0]:[0.0,0.0,2.497566674528029,0.0,0.0,0.0]:[0.0,0.0,2.3836373844361014,0.0,0.0,0.0]:[0.0,0.0,2.2682467231547347,0.0,0.0,0.0]:[0.0,0.0,2.1518711947254885,0.0,0.0,0.0]:[0.0,0.0,2.035,0.0,0.0,0.0]:[0.0,0.0,1.918128805274511,0.0,0.0,0.0]:[0.0,0.0,1.801753276845266,0.0,0.0,0.0]:[0.0,0.0,1.6863626155638975,0.0,0.0,0.0]:[0.0,0.0,1.5724333254719713,0.0,0.0,0.0]:[0.0,0.0,1.4604234341381717,0.0,0.0,0.0]:[0.0,0.0,1.3507673512974216,0.0,0.0,0.0]:[0.0,0.0,1.2438715102539866,0.0,0.0,0.0]:[0.0,0.0,1.1401108877231558,0.0,0.0,0.0]:[0.0,0.0,1.0398264471343923,0.0,0.0,0.0]:[0.0,0.0,0.9433235023521869,0.0,0.0,0.0]:[0.0,0.0,0.850870956877535,0.0,0.0,0.0]:[0.0,0.0,0.7627013402906222,0.0,0.0,0.0]:[0.0,0.0,0.6790115401457419,0.0,0.0,0.0]:[0.0,0.0,0.5999641137498641,0.0,0.0,0.0]:[0.0,0.0,0.5256890593625916,0.0,0.0,0.0]:[0.0,0.0,0.4562859288665133,0.0,0.0,0.0]:[0.0,0.0,0.39182617209928017,0.0,0.0,0.0]:[0.0,0.0,0.3323556150022027,0.0,0.0,0.0]:[0.0,0.0,0.27789698786807815,0.0,0.0,0.0]:[0.0,0.0,0.228452434874447,0.0,0.0,0.0]:[0.0,0.0,0.18400595069712544,0.0,0.0,0.0]:[0.0,0.0,0.14452570356038175,0.0,0.0,0.0]:[0.0,0.0,0.10996621612791468,0.0,0.0,0.0]:[0.0,0.0,0.08027038594162628,0.0,0.0,0.0]:[0.0,0.0,0.05537133562108121,0.0,0.0,0.0]:[0.0,0.0,0.035194089819686525,0.0,0.0,0.0]:[0.0,0.0,0.019657081148188205,0.0,0.0,0.0]:[0.0,0.0,0.008673491119354892,0.0,0.0,0.0] 10 | Far Zoom Out (30 FPS), ./motion_images/Far_Zoom_Out_(30 FPS).gif ,30 ,[0.0,0.0,0.0,0.0,0.0,0.0]:[0.0,0.0,0.0,0.0,0.0,0.0]:[0.0,0.0,0.0,0.0,0.0,0.0]:[0.0,0.0,-0.06783333333333331,0.0,0.0,0.0]:[0.0,0.0,-0.13566666666665678,0.0,0.0,0.0]:[0.0,0.0,-0.20349999999999996,0.0,0.0,0.0]:[0.0,0.0,-0.27133333333314935,0.0,0.0,0.0]:[0.0,0.0,-0.33916666666666434,0.0,0.0,0.0]:[0.0,0.0,-0.4069999999999999,0.0,0.0,0.0]:[0.0,0.0,-0.47483333333450395,0.0,0.0,0.0]:[0.0,0.0,-0.5426666666667481,0.0,0.0,0.0]:[0.0,0.0,-0.6105000000000059,0.0,0.0,0.0]:[0.0,0.0,-0.6783333333333337,0.0,0.0,0.0]:[0.0,0.0,-0.7461666666666668,0.0,0.0,0.0]:[0.0,0.0,-0.814,0.0,0.0,0.0]:[0.0,0.0,-0.8818333333333335,0.0,0.0,0.0]:[0.0,0.0,-0.9496666666666667,0.0,0.0,0.0]:[0.0,0.0,-1.0175,0.0,0.0,0.0]:[0.0,0.0,-1.0853333333333335,0.0,0.0,0.0]:[0.0,0.0,-1.153166666664133,0.0,0.0,0.0]:[0.0,0.0,-1.2209999999994459,0.0,0.0,0.0]:[0.0,0.0,-1.3566666666666465,0.0,0.0,0.0]:[0.0,0.0,-1.3566666666666465,0.0,0.0,0.0]:[0.0,0.0,-1.4244999999999965,0.0,0.0,0.0]:[0.0,0.0,-1.492333333333333,0.0,0.0,0.0]:[0.0,0.0,-1.5601666666666674,0.0,0.0,0.0]:[0.0,0.0,-1.6280000000000001,0.0,0.0,0.0]:[0.0,0.0,-1.695833333330795,0.0,0.0,0.0]:[0.0,0.0,-1.7636666666670977,0.0,0.0,0.0]:[0.0,0.0,-1.831500000000031,0.0,0.0,0.0]:[0.0,0.0,-1.899333333333334,0.0,0.0,0.0]:[0.0,0.0,-1.9671666666666665,0.0,0.0,0.0]:[0.0,0.0,-2.1028333333333338,0.0,0.0,0.0]:[0.0,0.0,-2.1028333333333338,0.0,0.0,0.0]:[0.0,0.0,-2.1706666666666665,0.0,0.0,0.0]:[0.0,0.0,-2.238499999999969,0.0,0.0,0.0]:[0.0,0.0,-2.3063333333329035,0.0,0.0,0.0]:[0.0,0.0,-2.374166666669206,0.0,0.0,0.0]:[0.0,0.0,-2.442,0.0,0.0,0.0]:[0.0,0.0,-2.509833333333334,0.0,0.0,0.0]:[0.0,0.0,-2.577666666666668,0.0,0.0,0.0]:[0.0,0.0,-2.6455000000000033,0.0,0.0,0.0]:[0.0,0.0,-2.713333333333354,0.0,0.0,0.0]:[0.0,0.0,-2.849000000000554,0.0,0.0,0.0]:[0.0,0.0,-2.849000000000554,0.0,0.0,0.0]:[0.0,0.0,-2.9168333333358674,0.0,0.0,0.0]:[0.0,0.0,-2.984666666666666,0.0,0.0,0.0]:[0.0,0.0,-3.0525,0.0,0.0,0.0]:[0.0,0.0,-3.1203333333333334,0.0,0.0,0.0]:[0.0,0.0,-3.1881666666666675,0.0,0.0,0.0]:[0.0,0.0,-3.2560000000000002,0.0,0.0,0.0]:[0.0,0.0,-3.3238333333333334,0.0,0.0,0.0]:[0.0,0.0,-3.391666666666667,0.0,0.0,0.0]:[0.0,0.0,-3.4594999999999945,0.0,0.0,0.0]:[0.0,0.0,-3.5273333333332517,0.0,0.0,0.0]:[0.0,0.0,-3.5951666666654964,0.0,0.0,0.0]:[0.0,0.0,-3.663,0.0,0.0,0.0]:[0.0,0.0,-3.7308333333333357,0.0,0.0,0.0]:[0.0,0.0,-3.798666666666851,0.0,0.0,0.0]:[0.0,0.0,-3.8665000000000007,0.0,0.0,0.0]:[0.0,0.0,-4.002166666666667,0.0,0.0,0.0]:[0.0,0.0,-4.002166666666667,0.0,0.0,0.0]:[0.0,0.0,-4.07,0.0,0.0,0.0]:[0.0,0.0,-4.07,0.0,0.0,0.0]:[0.0,0.0,-4.002166666666667,0.0,0.0,0.0]:[0.0,0.0,-3.9343333333333437,0.0,0.0,0.0]:[0.0,0.0,-3.8665000000000003,0.0,0.0,0.0]:[0.0,0.0,-3.798666666666851,0.0,0.0,0.0]:[0.0,0.0,-3.730833333333336,0.0,0.0,0.0]:[0.0,0.0,-3.6630000000000003,0.0,0.0,0.0]:[0.0,0.0,-3.5951666666654964,0.0,0.0,0.0]:[0.0,0.0,-3.527333333333252,0.0,0.0,0.0]:[0.0,0.0,-3.4594999999999945,0.0,0.0,0.0]:[0.0,0.0,-3.3916666666666666,0.0,0.0,0.0]:[0.0,0.0,-3.3238333333333334,0.0,0.0,0.0]:[0.0,0.0,-3.2560000000000002,0.0,0.0,0.0]:[0.0,0.0,-3.1881666666666666,0.0,0.0,0.0]:[0.0,0.0,-3.120333333333334,0.0,0.0,0.0]:[0.0,0.0,-3.0525,0.0,0.0,0.0]:[0.0,0.0,-2.9846666666666666,0.0,0.0,0.0]:[0.0,0.0,-2.9168333333358674,0.0,0.0,0.0]:[0.0,0.0,-2.8490000000005544,0.0,0.0,0.0]:[0.0,0.0,-2.713333333333354,0.0,0.0,0.0]:[0.0,0.0,-2.713333333333354,0.0,0.0,0.0]:[0.0,0.0,-2.6455000000000037,0.0,0.0,0.0]:[0.0,0.0,-2.509833333333333,0.0,0.0,0.0]:[0.0,0.0,-2.509833333333333,0.0,0.0,0.0]:[0.0,0.0,-2.442,0.0,0.0,0.0]:[0.0,0.0,-2.3741666666692054,0.0,0.0,0.0]:[0.0,0.0,-2.3063333333329026,0.0,0.0,0.0]:[0.0,0.0,-2.238499999999969,0.0,0.0,0.0]:[0.0,0.0,-2.1706666666666665,0.0,0.0,0.0]:[0.0,0.0,-2.1028333333333338,0.0,0.0,0.0]:[0.0,0.0,-2.035,0.0,0.0,0.0]:[0.0,0.0,-1.9671666666666665,0.0,0.0,0.0]:[0.0,0.0,-1.8993333333333338,0.0,0.0,0.0]:[0.0,0.0,-1.8315000000000312,0.0,0.0,0.0]:[0.0,0.0,-1.7636666666670968,0.0,0.0,0.0]:[0.0,0.0,-1.6958333333307944,0.0,0.0,0.0]:[0.0,0.0,-1.6280000000000001,0.0,0.0,0.0]:[0.0,0.0,-1.5601666666666665,0.0,0.0,0.0]:[0.0,0.0,-1.4923333333333324,0.0,0.0,0.0]:[0.0,0.0,-1.424499999999997,0.0,0.0,0.0]:[0.0,0.0,-1.3566666666666465,0.0,0.0,0.0]:[0.0,0.0,-1.2888333333332214,0.0,0.0,0.0]:[0.0,0.0,-1.2209999999994463,0.0,0.0,0.0]:[0.0,0.0,-1.153166666664133,0.0,0.0,0.0]:[0.0,0.0,-1.0853333333333341,0.0,0.0,0.0]:[0.0,0.0,-1.0175,0.0,0.0,0.0]:[0.0,0.0,-0.9496666666666669,0.0,0.0,0.0]:[0.0,0.0,-0.8818333333333328,0.0,0.0,0.0]:[0.0,0.0,-0.8140000000000001,0.0,0.0,0.0]:[0.0,0.0,-0.7461666666666669,0.0,0.0,0.0]:[0.0,0.0,-0.6783333333333332,0.0,0.0,0.0]:[0.0,0.0,-0.6105000000000058,0.0,0.0,0.0]:[0.0,0.0,-0.5426666666667486,0.0,0.0,0.0]:[0.0,0.0,-0.47483333333450384,0.0,0.0,0.0]:[0.0,0.0,-0.4070000000000005,0.0,0.0,0.0]:[0.0,0.0,-0.3391666666666646,0.0,0.0,0.0]:[0.0,0.0,-0.27133333333314935,0.0,0.0,0.0]:[0.0,0.0,-0.20349999999999957,0.0,0.0,0.0]:[0.0,0.0,-0.13566666666665705,0.0,0.0,0.0]:[0.0,0.0,-0.06783333333333363,0.0,0.0,0.0] 11 | -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/arm_off.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/arm_off.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/arm_on.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/arm_on.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/down_arrow.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/down_arrow.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/forward_closest.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/forward_closest.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/left_arrow.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/left_arrow.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/lock_off.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/lock_off.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/lock_on.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/lock_on.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/look_down.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/look_down.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/look_left.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/look_left.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/look_right.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/look_right.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/look_upp.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/look_upp.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/parseq_off.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/parseq_off.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/parseq_on.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/parseq_on.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/play.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/play.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/record_off.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/record_off.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/record_on.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/record_on.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/record_recording.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/record_recording.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/reverse_fov_off.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/reverse_fov_off.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/reverse_fov_on.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/reverse_fov_on.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/rewind_closest.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/rewind_closest.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/right_arrow.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/right_arrow.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/rotate_left.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/rotate_left.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/rotate_right.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/rotate_right.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/stop.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/stop.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/upp_arrow.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/upp_arrow.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/zero.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/zero.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/images/zero_active.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/images/zero_active.bmp -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/motion_images/Far_Zoom_In_(30 FPS).gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/motion_images/Far_Zoom_In_(30 FPS).gif -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/motion_images/Far_Zoom_Out_(30 FPS).gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/motion_images/Far_Zoom_Out_(30 FPS).gif -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/motion_images/close_rotation_left.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/motion_images/close_rotation_left.gif -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/motion_images/close_rotation_right.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/motion_images/close_rotation_right.gif -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/motion_images/far_rotation_left.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/motion_images/far_rotation_left.gif -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/motion_images/far_rotation_right.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/motion_images/far_rotation_right.gif -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/motion_images/medium_rotation_left.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/motion_images/medium_rotation_left.gif -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/motion_images/medium_rotation_right.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/Version_0.7.6/deforumation/motion_images/medium_rotation_right.gif -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/requirements.txt: -------------------------------------------------------------------------------- 1 | websockets == 10.4 2 | wxPython >= 4.2.0 3 | keyboard >= 0.13.5 4 | requests 5 | pyeaze 6 | pytest-shutil 7 | pyaudio 8 | SpeechRecognition 9 | pywin32 10 | -------------------------------------------------------------------------------- /Version_0.7.6/deforumation/run_me_first_install_requirements.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | start python -m pip install -r requirements.txt 3 | timeout /t 0.5 /nobreak > NUL 4 | -------------------------------------------------------------------------------- /github_images/Aiwakening.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/Aiwakening.png -------------------------------------------------------------------------------- /github_images/DM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/DM.png -------------------------------------------------------------------------------- /github_images/DMQT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/DMQT.png -------------------------------------------------------------------------------- /github_images/DMQTyou.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/DMQTyou.png -------------------------------------------------------------------------------- /github_images/Deforumation_Tutorial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/Deforumation_Tutorial.png -------------------------------------------------------------------------------- /github_images/Linol_1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/Linol_1.PNG -------------------------------------------------------------------------------- /github_images/Live_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/Live_preview.png -------------------------------------------------------------------------------- /github_images/aixite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/aixite.png -------------------------------------------------------------------------------- /github_images/arm_off.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/arm_off.bmp -------------------------------------------------------------------------------- /github_images/arm_on.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/arm_on.bmp -------------------------------------------------------------------------------- /github_images/controlnet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/controlnet.png -------------------------------------------------------------------------------- /github_images/current_version.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/current_version.png -------------------------------------------------------------------------------- /github_images/current_version_gentle_zero_rotation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/current_version_gentle_zero_rotation.png -------------------------------------------------------------------------------- /github_images/deforumation_design_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/deforumation_design_01.jpg -------------------------------------------------------------------------------- /github_images/install.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/install.PNG -------------------------------------------------------------------------------- /github_images/newinterface4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/newinterface4.png -------------------------------------------------------------------------------- /github_images/newinterface5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/newinterface5.png -------------------------------------------------------------------------------- /github_images/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/output.gif -------------------------------------------------------------------------------- /github_images/panning.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/panning.PNG -------------------------------------------------------------------------------- /github_images/patreon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/patreon.png -------------------------------------------------------------------------------- /github_images/replay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/replay.png -------------------------------------------------------------------------------- /github_images/resume.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/resume.PNG -------------------------------------------------------------------------------- /github_images/rewindforward.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/rewindforward.PNG -------------------------------------------------------------------------------- /github_images/rotation.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/rotation.PNG -------------------------------------------------------------------------------- /github_images/smile.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/smile.gif -------------------------------------------------------------------------------- /github_images/strengthCFG.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/strengthCFG.PNG -------------------------------------------------------------------------------- /github_images/tilt.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/tilt.PNG -------------------------------------------------------------------------------- /github_images/zero.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rakile/deforumation/b2812a3914b0d40876ef756b4e7da89b9c8b6d2d/github_images/zero.bmp --------------------------------------------------------------------------------