We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hello Community,
Thank you in advance for reading.
The children in our free school have been given coloring book with animal drawings in it. While children are coloring the books, I am planning to live-project these colored animals in form of a simple story by launching them in processing and making them move/run/hide (un-animated).
Is there a way, I can programming processing to auto-mask/crop these animal pictures (scanned from phone) to give only the animal shape while deleting all white space around the drawing.
Am not sure where to start looking. Any help highly welcome and appreciated.
Raj
Sampling paper example - https://goo.gl/24jQZg
Answers
I think it is doable. If all the animals(pictures) have a well defined contour, then I can imagine applying the magic wand example provided by @jeremydouglass to the 4 corners of the picture.
What is the magic wand (flood fill) algorithm? It ensures all pixels around certain pixel is painted certain color
Why the four corners of the picture? I am assuming that the image of interest is at the center of the picture. Then I am assuming (again) that if I flood fill all the four corners (tips of the picture), then I can attack the background with the same color.
So what happened to the background of the picture from your student? The background of the photo gets flood fill with this color: 0x00000000 which means that the background is set to transparent (More in the reference here: Alpha + Transparency)
Now, @jeremydouglass has shared a demo using the magic wand here: https://forum.processing.org/two/discussion/comment/101833#Comment_101833
Next, for your case, and because we are going to be working with transparencies, we are forced to work with PGraphics objects as this kind of objects honors the transparency attribute. Check more here: https://processing.org/reference/createGraphics_.html
However, we still need one more trick. To save the file in Processing and when working with PGraphics, we need to work with @pandanautinspace and @GoToLoop's trick as mentioned here in this post https://forum.processing.org/two/discussion/17320/likely-a-bug-processing-can-t-save-different-pgraphics-of-different-sizes. In a nutshell, if you call PGraphics.save(), it is very likely you will get a null point exception. The trick in the above post solves the issue.
Finally, here I present my demo for you to use. First, I downloaded three images and I put my Picasso's hat. Then I saved the images. You can access the images below. Make sure you save those images in the data folder of the sketch (I am assuming you know how Processing works. If you have any doubts, just ask). Then run the script. The script will load each image one at the time, show it to you for half second and then it will process it as described above. The image is saved in the sketch folder. After it finishes processing all three images, it goes into a second stage where it shows all three images randomly in the sketch to give it a "collage" look. Any click event on the canvas randomly places the images in a new position with a different shaded background.
Kf
@krafzer - gratitude from Cambodia. Promise to share pics how its used. in couple of weeks.
@krafzer - I found a video of what I imagined already done here : https://www.facebook.com/teamLab.inc/videos/10154570445785940 . Ofcourse not at this scale. We don't have such resources :) .. Just wanted to share with you. I am working and making progress albeit very slowly ..
@raj Nice and very Interesting... all of it can be done in Processing. I guess the moving figures need to be known beforehand. For example, the flying bird... kids will paint a standard flying figure. When you scan the figure, you will have a sprite, a set of figures that together represents some motion, and you map the scan main figure to the sprite version.... and voila, there you have, your figure moving using a provided pattern... the end result will be like a gif file. The last effect can be accomplish using PGraphics objects overlaid with decreasing alpha values.
Kf
Atleast someone else believes my crazy vision :) Honestly - I didn't figure until this far yet. But thanks for knitting it together. I would like to try and see how far I can go :)
See also for example
That spider is just a single, simple mask, but you could map the legs separately (rather than creating a single cut-out) and then you would have a simple illusion of painted limbs -- not unlike like the more complex lizards and birds etc. in your reference video.
@jeremydouglass - thank you. i like the spider movement. PGraphics looks like way to go about it. Yes with very subtle and simple animation plus numbers of such pre-determined animals/insects colored by many kids will fill the wall.
Hi @kfrajer - hope you are doing well. With your example above, I extended it to work on multiple folders with different set of images. To make the process easy. Works very well. However pg.save gives a run time error.
"Waiting 5000ms ...... "
I have attached the folder for your reference. In the attached link in file floodfill.pde - if I remove the comment on line #127, I get the error.
line 127# //pg.save("/data/Rockets/image"+imagesInFolder+".png");
Been trying for few weeks and also asked my friends but no luck. So reaching our to you directly. Any help or direction is highly appreciated. thank you a lot.
Hey, I saw some posts that you might find interesting:
https://www.giraffest.ca/brandon-hearty
http://www.ivanguaderrama.com/blog/our-new-app-is-out
Related to your question, if you comment out all the references to spout, the error goes away. I am not familiar with spout. What are you using it for? Calling it and sending data in your draw() function is the culprit. You are firing spout and sending data at a rate of 30 fps. If you tell us more of what you want to do, I am sure there is a more convenient way to do this. After I remove your spout references, I am getting sporadic NPE (See below) but they do not halt your program. It could be related to accessing the movie object.
Notice that after I am able to run your program, the carriages and rockets seems to be drawn in the same image. You might want to revise that part of the code.
Kf
Folder Name === C:\Users\C\Downloads\FloodFillandMove-20171123T035320Z-001\FloodFillandMove/data/4KStogram/BoatsInstagram index =0 =====studentsImgs{imagesInFolder] ==B1.jpg Folder Name === C:\Users\C\Downloads\FloodFillandMove-20171123T035320Z-001\FloodFillandMove/data/4KStogram/BoatsInstagram index =1 =====studentsImgs{imagesInFolder] ==B2.jpg Folder Name === C:\Users\C\Downloads\FloodFillandMove-20171123T035320Z-001\FloodFillandMove/data/4KStogram/BoatsInstagram index =2 =====studentsImgs{imagesInFolder] ==B3.jpg Folder Name === C:\Users\C\Downloads\FloodFillandMove-20171123T035320Z-001\FloodFillandMove/data/4KStogram/CarriagesInstagram index =0 =====studentsImgs{imagesInFolder] ==C1.jpg Folder Name === C:\Users\C\Downloads\FloodFillandMove-20171123T035320Z-001\FloodFillandMove/data/4KStogram/CarriagesInstagram index =1 =====studentsImgs{imagesInFolder] ==C2.jpg Folder Name === C:\Users\C\Downloads\FloodFillandMove-20171123T035320Z-001\FloodFillandMove/data/4KStogram/CarriagesInstagram index =2 =====studentsImgs{imagesInFolder] ==C3.jpg Folder Name === C:\Users\C\Downloads\FloodFillandMove-20171123T035320Z-001\FloodFillandMove/data/4KStogram/CarriagesInstagram index =3 =====studentsImgs{imagesInFolder] ==C4.jpg Folder Name === C:\Users\C\Downloads\FloodFillandMove-20171123T035320Z-001\FloodFillandMove/data/4KStogram/RocketsInstgram index =0 =====studentsImgs{imagesInFolder] ==image0.png Folder Name === C:\Users\C\Downloads\FloodFillandMove-20171123T035320Z-001\FloodFillandMove/data/4KStogram/RocketsInstgram index =1 =====studentsImgs{imagesInFolder] ==image1.png Folder Name === C:\Users\C\Downloads\FloodFillandMove-20171123T035320Z-001\FloodFillandMove/data/4KStogram/RocketsInstgram index =2 =====studentsImgs{imagesInFolder] ==image2.png Folder Name === C:\Users\C\Downloads\FloodFillandMove-20171123T035320Z-001\FloodFillandMove/data/4KStogram/RocketsInstgram index =3 =====studentsImgs{imagesInFolder] ==image3.png java.lang.NullPointerException at processing.opengl.Texture.copyBufferFromSource(Texture.java:827) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at processing.video.Movie.read(Unknown Source) at FloodFillandMove.movieEvent(FloodFillandMove.java:83) at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at processing.video.Movie.fireMovieEvent(Unknown Source) at processing.video.Movie.invokeEvent(Unknown Source) at processing.video.Movie$1.bufferFrame(Unknown Source) at org.gstreamer.elements.BufferDataAppSink$AppSinkNewBufferListener.newBuffer(BufferDataAppSink.java:163) at org.gstreamer.elements.AppSink$2.callback(AppSink.java:184) at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.sun.jna.CallbackReference$DefaultCallbackProxy.invokeCallback(CallbackReference.java:485) at com.sun.jna.CallbackReference$DefaultCallbackProxy.callback(CallbackReference.java:515) java.lang.NullPointerException at processing.opengl.Texture.copyBufferFromSource(Texture.java:827) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at processing.video.Movie.read(Unknown Source) at FloodFillandMove.movieEvent(FloodFillandMove.java:83) at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at processing.video.Movie.fireMovieEvent(Unknown Source) at processing.video.Movie.invokeEvent(Unknown Source) at processing.video.Movie$1.bufferFrame(Unknown Source) at org.gstreamer.elements.BufferDataAppSink$AppSinkNewBufferListener.newBuffer(BufferDataAppSink.java:163) at org.gstreamer.elements.AppSink$2.callback(AppSink.java:184) at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.sun.jna.CallbackReference$DefaultCallbackProxy.invokeCallback(CallbackReference.java:485) at com.sun.jna.CallbackReference$DefaultCallbackProxy.callback(CallbackReference.java:515) java.lang.NullPointerException at processing.opengl.Texture.copyBufferFromSource(Texture.java:827) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at processing.video.Movie.read(Unknown Source) at FloodFillandMove.movieEvent(FloodFillandMove.java:83) at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at processing.video.Movie.fireMovieEvent(Unknown Source) at processing.video.Movie.invokeEvent(Unknown Source) at processing.video.Movie$1.bufferFrame(Unknown Source) at org.gstreamer.elements.BufferDataAppSink$AppSinkNewBufferListener.newBuffer(BufferDataAppSink.java:163) at org.gstreamer.elements.AppSink$2.callback(AppSink.java:184) at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.sun.jna.CallbackReference$DefaultCallbackProxy.invokeCallback(CallbackReference.java:485) at com.sun.jna.CallbackReference$DefaultCallbackProxy.callback(CallbackReference.java:515) java.lang.NullPointerException at processing.opengl.Texture.copyBufferFromSource(Texture.java:827) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at processing.video.Movie.read(Unknown Source) at FloodFillandMove.movieEvent(FloodFillandMove.java:83) at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at processing.video.Movie.fireMovieEvent(Unknown Source) at processing.video.Movie.invokeEvent(Unknown Source) at processing.video.Movie$1.bufferFrame(Unknown Source) at org.gstreamer.elements.BufferDataAppSink$AppSinkNewBufferListener.newBuffer(BufferDataAppSink.java:163) at org.gstreamer.elements.AppSink$2.callback(AppSink.java:184) at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.sun.jna.CallbackReference$DefaultCallbackProxy.invokeCallback(CallbackReference.java:485) at com.sun.jna.CallbackReference$DefaultCallbackProxy.callback(CallbackReference.java:515) java.lang.NullPointerException at processing.opengl.Texture.copyBufferFromSource(Texture.java:827) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at processing.video.Movie.read(Unknown Source) at FloodFillandMove.movieEvent(FloodFillandMove.java:83) at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at processing.video.Movie.fireMovieEvent(Unknown Source) at processing.video.Movie.invokeEvent(Unknown Source) at processing.video.Movie$1.bufferFrame(Unknown Source) at org.gstreamer.elements.BufferDataAppSink$AppSinkNewBufferListener.newBuffer(BufferDataAppSink.java:163) at org.gstreamer.elements.AppSink$2.callback(AppSink.java:184) at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.sun.jna.CallbackReference$DefaultCallbackProxy.invokeCallback(CallbackReference.java:485) at com.sun.jna.CallbackReference$DefaultCallbackProxy.callback(CallbackReference.java:515) java.lang.NullPointerException at processing.opengl.Texture.copyBufferFromSource(Texture.java:827) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at processing.video.Movie.read(Unknown Source) at FloodFillandMove.movieEvent(FloodFillandMove.java:83) at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at processing.video.Movie.fireMovieEvent(Unknown Source) at processing.video.Movie.invokeEvent(Unknown Source) at processing.video.Movie$1.bufferFrame(Unknown Source) at org.gstreamer.elements.BufferDataAppSink$AppSinkNewBufferListener.newBuffer(BufferDataAppSink.java:163) at org.gstreamer.elements.AppSink$2.callback(AppSink.java:184) at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.sun.jna.CallbackReference$DefaultCallbackProxy.invokeCallback(CallbackReference.java:485) at com.sun.jna.CallbackReference$DefaultCallbackProxy.callback(CallbackReference.java:515) java.lang.NullPointerException at processing.opengl.Texture.copyBufferFromSource(Texture.java:827) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at processing.video.Movie.read(Unknown Source) at FloodFillandMove.movieEvent(FloodFillandMove.java:83) at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at processing.video.Movie.fireMovieEvent(Unknown Source) at processing.video.Movie.invokeEvent(Unknown Source) at processing.video.Movie$1.bufferFrame(Unknown Source) at org.gstreamer.elements.BufferDataAppSink$AppSinkNewBufferListener.newBuffer(BufferDataAppSink.java:163) at org.gstreamer.elements.AppSink$2.callback(AppSink.java:184) at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.sun.jna.CallbackReference$DefaultCallbackProxy.invokeCallback(CallbackReference.java:485) at com.sun.jna.CallbackReference$DefaultCallbackProxy.callback(CallbackReference.java:515) reszing reszing size = 86 xPos=Ypos=748 reszing reszing reszing reszing reszing reszing
Thank you a lot kfrazer. It worked. I use spout to bring the processing sketch into resolume arena (projection mapping software) to project on 3D surface as we don't find plain 2D surfaces all the time in areas we do these social activities.
Yes , i have to fix the overlapping :).