{"id":2058,"date":"2016-07-02T07:19:20","date_gmt":"2016-07-02T06:19:20","guid":{"rendered":"http:\/\/johnjohnston.info\/106\/?p=2058"},"modified":"2016-07-03T18:09:04","modified_gmt":"2016-07-03T17:09:04","slug":"this-aint-no-rotoscope","status":"publish","type":"post","link":"https:\/\/johnjohnston.info\/106\/this-aint-no-rotoscope\/","title":{"rendered":"This ain&#8217;t no Rotoscope"},"content":{"rendered":"<p>As usual it started with a tweet:<\/p>\n<blockquote class=\"twitter-tweet\" data-width=\"550\">\n<p lang=\"en\" dir=\"ltr\"><a href=\"https:\/\/twitter.com\/mdvfunes\">@mdvfunes<\/a> <a href=\"https:\/\/twitter.com\/phb256\">@phb256<\/a> <a href=\"https:\/\/twitter.com\/johnjohnston\">@johnjohnston<\/a> So this would be an excellent example of <a href=\"https:\/\/twitter.com\/hashtag\/ds106?src=hash\">#ds106<\/a> SPLOT, port to a web version and bam <a href=\"https:\/\/t.co\/sPUgFVKqIT\">https:\/\/t.co\/sPUgFVKqIT<\/a><\/p>\n<p>&mdash; Jim Groom (@jimgroom) <a href=\"https:\/\/twitter.com\/jimgroom\/status\/748469700946956288\">June 30, 2016<\/a><\/p><\/blockquote>\n<p><script async src=\"\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><\/p>\n<p>The referenced tweet looked interesting:<\/p>\n<blockquote class=\"twitter-tweet\" data-width=\"550\">\n<p lang=\"en\" dir=\"ltr\">RT for the early birds&#8230; <a href=\"https:\/\/t.co\/OAXUuDbgY7\">https:\/\/t.co\/OAXUuDbgY7<\/a><\/p>\n<p>&mdash; Cartoon Brew (@cartoonbrew) <a href=\"https:\/\/twitter.com\/cartoonbrew\/status\/748189825166086144\">June 29, 2016<\/a><\/p><\/blockquote>\n<p><script async src=\"\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><\/p>\n<p>I&#8217;ve tried Rotoscoping before, but this looked good. I hied over to <a href=\"https:\/\/itch.io\/t\/28458\/macososx\">MacOS\/OSX &#8211; Paint of Persia community &#8211; itch.io<\/a>, read about it. paid $5 and set things up.<\/p>\n<p>At that point I realise that the app helps you to manually trace frames, seemed a wee bit time consuming. I though I&#8217;d leave it for another day. I did start musing on doing something similar, I was thinging <a href=\"https:\/\/ffmpeg.org\/\">FFmpeg<\/a> &amp; <a href=\"http:\/\/www.imagemagick.org\/script\/index.php\">ImageMagick<\/a>.<\/p>\n<p>Google takes me to <a href=\"http:\/\/www.fmwconcepts.com\/imagemagick\/cartoon\/\">Fred&#8217;s ImageMagick Scripts: CARTOON<\/a>.<\/p>\n<p>so the plan is:<\/p>\n<ol>\n<li>export a movie to a series of images.<\/li>\n<li>cartoonise those image<\/li>\n<li>create a move from the cartoon images<\/li>\n<\/ol>\n<p>Bounus points for getting the sound track back in.<\/p>\n<p>I already have ffmpeg &amp; imagemagick installed on my mac. These are commandline tools.<\/p>\n<p>I downloaded the cartoon script<\/p>\n<p>First find a video:<\/p>\n<div class=\"jetpack-video-wrapper\"><iframe loading=\"lazy\" title=\"The Shower - Psycho (5\/12) Movie CLIP (1960) HD\" width=\"840\" height=\"473\" src=\"https:\/\/www.youtube.com\/embed\/0WtDmbr9xyY?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/div>\n<p><a href=\"http:\/\/fastesttube.kwizzu.com\/\">YouTube downloader tool &#8211; Fastesttube!<\/a><\/p>\n<p>Rename the downloaded file <em>shower.mp4<\/em><\/p>\n<p>Open the terminal and cd into the folder that has the cartoon script and the movie in it.<\/p>\n<p>First extract lots of still images (make a folder shower first <code>mkdir shower<\/code>):<\/p>\n<p><code>ffmpeg -i shower.mp4 -r 6 shower\/out_%04d.jpg<\/code><\/p>\n<p>this takes the input file (-i) at 6 frames per second and create jpg files in the shower folder with the file name out_0001.jpg ,out_0002.jpg ect<\/p>\n<p>Given the movie is 3 minutes 22 seconds long I end up with 1212 images in the folder. I delete the last few manually to give me 1023 images.<\/p>\n<p>I now need to loop through all of those images and create a cartoon version.<\/p>\n<p>the use of cartoon is basically:<\/p>\n<p><code>.\/cartoon face.jpg temp.jpg<\/code><\/p>\n<p>There are some paramaters you can use but I stuck to the default.<\/p>\n<p>This would take the image on the left and create the one on the right:<\/p>\n<p><a href=\"http:\/\/johnjohnston.info\/106\/wp-content\/uploads\/2016\/07\/face.out_.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2060\" src=\"https:\/\/johnjohnston.info\/106\/wp-content\/uploads\/2016\/07\/face.out_.jpg\" alt=\"face.out\" width=\"600\" height=\"200\" srcset=\"https:\/\/johnjohnston.info\/106\/wp-content\/uploads\/2016\/07\/face.out_.jpg 600w, https:\/\/johnjohnston.info\/106\/wp-content\/uploads\/2016\/07\/face.out_-300x100.jpg 300w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><\/a><\/p>\n<p>So I move into the shower folder <code>cd shower<\/code><\/p>\n<p><code>mkdir out;for i in *.jpg; do ..\/cartoon $i out\/$i.jpg;done<\/code><\/p>\n<p>this script:<br \/>\nmakes a nother folder called out<\/p>\n<p><em>for i in *.jpg<\/em> for each file with a .jpg extension in the current folder <em>do<\/em> does:<\/p>\n<p><em>..\/cartoon $i out\/$i.jpg<\/em> runs the cartoon script from the folder above (..\/), and saves the output file in the out folder with the same name.<\/p>\n<p>When I kicked this off I quickly realised it would take a while to r=un through 1212 images, so went to bed.<\/p>\n<p>The next morning I have 1023 cartoons (I don&#8217;t imagine that it took all night).<br \/>\n<a href=\"http:\/\/johnjohnston.info\/106\/wp-content\/uploads\/2016\/07\/out_0672.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-2065\" src=\"https:\/\/johnjohnston.info\/106\/wp-content\/uploads\/2016\/07\/out_0672.jpg\" alt=\"out_0672\" width=\"640\" height=\"360\" srcset=\"https:\/\/johnjohnston.info\/106\/wp-content\/uploads\/2016\/07\/out_0672.jpg 640w, https:\/\/johnjohnston.info\/106\/wp-content\/uploads\/2016\/07\/out_0672-300x169.jpg 300w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><\/a><\/p>\n<p>Time to stich these together, it took me a few goes to get the paramaters right. (google helps).<\/p>\n<p><code>ffmpeg -f image2 -framerate 6 -i out_%04d.jpg -c:v libx264 -pix_fmt yuv420p out.mp4<\/code><\/p>\n<ol>\n<li>-f chooses the format image2 which makes an image sequence.<\/li>\n<li>-framerate 6 to get the smae length of movie as I started with<\/li>\n<li>-i infiles confusinging names out_0001.jpg ect the <em>%04d<\/em> means look for 4 figured numbers starting with 0001<\/li>\n<li>-c codec<\/li>\n<li>-pix_fmt is the pixel format, I dn&#8217;t know much about these but the script failed until I added it in<\/li>\n<\/ol>\n<p>It took me a few shots until I got this right.<\/p>\n<p>I then moved the out.mp4 video to the same folder as the original and<\/p>\n<p><code>ffmpeg -i shower.mp4 -acodec copy -vn shower-audio.mp4<\/code><\/p>\n<p>To extract the audio from the original file.<\/p>\n<p>then:<\/p>\n<p><code>ffmpeg -i out.mp4 -i shower-audio.mp4 -vcodec copy -acodec copy -shortest final.mp4<\/code><\/p>\n<p>To add the audio from the original to the out video to give me a final one.<\/p>\n<p>the -shortest parameter gets rid of the audio at the end to make up for the frames I removed.<\/p>\n<p>Bingo:<\/p>\n<div style=\"width: 640px;\" class=\"wp-video\"><!--[if lt IE 9]><script>document.createElement('video');<\/script><![endif]-->\n<video class=\"wp-video-shortcode\" id=\"video-2058-1\" width=\"640\" height=\"360\" poster=\"http:\/\/johnjohnston.info\/106\/wp-content\/uploads\/2016\/07\/out_0344.jpg\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"http:\/\/johnjohnston.info\/106\/wp-content\/uploads\/2016\/07\/final.mp4?_=1\" \/><a href=\"http:\/\/johnjohnston.info\/106\/wp-content\/uploads\/2016\/07\/final.mp4\">http:\/\/johnjohnston.info\/106\/wp-content\/uploads\/2016\/07\/final.mp4<\/a><\/video><\/div>\n<p>At this point I remembered iMovie has a comic filter&#8230;<\/p>\n<p>This post is mostly as an aid to my occasional dip into the world of commandline video editing. Posting helps me remember. It also plays a wee bit fast and loose with copyright.<\/p>\n<p><em>The featured image is a gif giffed from a few of the stills.<\/em><\/p>\n<p>ps this is quite a disturbing clip, I didn&#8217;t really watch it till I finished, could have picked a nice one!<\/p>\n<p><strong>Update, Ron commented<\/strong>:<\/p>\n<div class=\"comment-content\">\n<blockquote><p>What would it look like if you\u2019d run the result videos through the script one more time. Keeping the same number of jpegs but making the lines more stand out and the fills less so you\u2019d have black outlines and white?<\/p><\/blockquote>\n<p>That didn&#8217;t make much difference os I did some <a href=\"http:\/\/cartoon-params.surge.sh\">tests\u00a0with the parameters for cartoon<\/a>, and Ron went with increasing the brightness:<code>\u00a0..\/cartoon -b 300<\/code><\/p>\n<blockquote class=\"twitter-tweet\" data-width=\"550\">\n<p lang=\"en\" dir=\"ltr\"><a href=\"https:\/\/twitter.com\/johnjohnston\">@johnjohnston<\/a> <a href=\"https:\/\/twitter.com\/jimgroom\">@jimgroom<\/a> <br \/>Brightness 300 looks strong. The big contrast adds to the effect. <br \/>I&#39;m often searching for using little as possible<\/p>\n<p>&mdash; Ronald_2008 (@ronald_2008) <a href=\"https:\/\/twitter.com\/ronald_2008\/status\/749235924429639680\">July 2, 2016<\/a><\/p><\/blockquote>\n<p><script async src=\"\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><\/p>\n<p>This gave me this:<\/p>\n<\/div>\n<div style=\"width: 640px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-2058-2\" width=\"640\" height=\"360\" poster=\"http:\/\/johnjohnston.info\/106\/wp-content\/uploads\/2016\/07\/out_0280.jpg\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"http:\/\/johnjohnston.info\/106\/wp-content\/uploads\/2016\/07\/ron-audio.mp4?_=2\" \/><a href=\"http:\/\/johnjohnston.info\/106\/wp-content\/uploads\/2016\/07\/ron-audio.mp4\">http:\/\/johnjohnston.info\/106\/wp-content\/uploads\/2016\/07\/ron-audio.mp4<\/a><\/video><\/div>\n","protected":false},"excerpt":{"rendered":"<p>As usual it started with a tweet: @mdvfunes @phb256 @johnjohnston So this would be an excellent example of #ds106 SPLOT, port to a web version and bam https:\/\/t.co\/sPUgFVKqIT &mdash; Jim Groom (@jimgroom) June 30, 2016 The referenced tweet looked interesting: RT for the early birds&#8230; https:\/\/t.co\/OAXUuDbgY7 &mdash; Cartoon Brew (@cartoonbrew) June 29, 2016 I&#8217;ve tried &hellip; <a href=\"https:\/\/johnjohnston.info\/106\/this-aint-no-rotoscope\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;This ain&#8217;t no Rotoscope&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":2061,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[229],"tags":[230,179,153,181,152],"class_list":["post-2058","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-video","tag-bash","tag-ffmpeg","tag-fun","tag-imagemagick","tag-video"],"better_featured_image":{"id":2061,"alt_text":"","caption":"","description":"","media_type":"image","media_details":{"width":640,"height":360,"file":"2016\/07\/shower.gif","sizes":{"thumbnail":{"file":"shower-150x150.gif","width":150,"height":150,"mime-type":"image\/gif","source_url":"https:\/\/johnjohnston.info\/106\/wp-content\/uploads\/2016\/07\/shower-150x150.gif"},"medium":{"file":"shower-300x169.gif","width":300,"height":169,"mime-type":"image\/gif","source_url":"https:\/\/johnjohnston.info\/106\/wp-content\/uploads\/2016\/07\/shower-300x169.gif"}},"image_meta":{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0","keywords":[]}},"post":2058,"source_url":"https:\/\/johnjohnston.info\/106\/wp-content\/uploads\/2016\/07\/shower.gif"},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/johnjohnston.info\/106\/wp-content\/uploads\/2016\/07\/shower.gif","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p3RLlC-xc","_links":{"self":[{"href":"https:\/\/johnjohnston.info\/106\/wp-json\/wp\/v2\/posts\/2058","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/johnjohnston.info\/106\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/johnjohnston.info\/106\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/johnjohnston.info\/106\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/johnjohnston.info\/106\/wp-json\/wp\/v2\/comments?post=2058"}],"version-history":[{"count":10,"href":"https:\/\/johnjohnston.info\/106\/wp-json\/wp\/v2\/posts\/2058\/revisions"}],"predecessor-version":[{"id":2079,"href":"https:\/\/johnjohnston.info\/106\/wp-json\/wp\/v2\/posts\/2058\/revisions\/2079"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/johnjohnston.info\/106\/wp-json\/wp\/v2\/media\/2061"}],"wp:attachment":[{"href":"https:\/\/johnjohnston.info\/106\/wp-json\/wp\/v2\/media?parent=2058"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/johnjohnston.info\/106\/wp-json\/wp\/v2\/categories?post=2058"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/johnjohnston.info\/106\/wp-json\/wp\/v2\/tags?post=2058"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}