Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Whiteboard Picture Cleaner - Shell one-liner/script to clean up and beautify photos of whiteboards!

Description

This simple script will take a picture of a whiteboard and use parts of the ImageMagick library with sane defaults to clean it up tremendously.

The script is here:

#!/bin/bash
convert "$1" -morphology Convolve DoG:15,100,0 -negate -normalize -blur 0x1 -channel RBG -level 60%,91%,0.1 "$2"

Results

Here are some of the input images:

And here are the results:

Usage

Assuming it's saved as a file named whiteboardClean.sh, the command is ./whiteboardClean.sh {name of input file} {name of file to output to}.

Here's an example:

./whiteboardClean.sh example1.jpg output1.png

How I Came Up With This

I was doing a lot work with whiteboards and I'd been taking pictures of them to document what had been written. I wanted a more clean version of the pictures though, something that captured the essence of what a whiteboard image showed.

Eventually I found this excellent guide to cleaning up whiteboard photos using GIMP. However, I found I wanted more automation. So, I spent a few hours yesterday figuring out how to do the same thing using ImageMagick from the command line and made this script.

@tekknolagi

This comment has been minimized.

Show comment
Hide comment
@tekknolagi

tekknolagi Apr 3, 2014

Definitely make it into a bash/zsh alias :)

Definitely make it into a bash/zsh alias :)

@jacobsmith

This comment has been minimized.

Show comment
Hide comment
@jacobsmith

jacobsmith Apr 3, 2014

This would be great to hook up to a webcam that constantly takes pictures of a whiteboard (or with the press of a button) for documenting brainstorming sessions

This would be great to hook up to a webcam that constantly takes pictures of a whiteboard (or with the press of a button) for documenting brainstorming sessions

@kreely

This comment has been minimized.

Show comment
Hide comment
@kreely

kreely Apr 3, 2014

This is great. Well done.

kreely commented Apr 3, 2014

This is great. Well done.

@johndeng

This comment has been minimized.

Show comment
Hide comment
@johndeng

johndeng Apr 3, 2014

So great. I love it.

johndeng commented Apr 3, 2014

So great. I love it.

@magus

This comment has been minimized.

Show comment
Hide comment
@magus

magus Apr 3, 2014

Not experiencing the same results with the same example images.

⇨ convert -version Version: ImageMagick 6.8.6-3 2014-03-23 Q16 http://www.imagemagick.org Copyright: Copyright (C) 1999-2013 ImageMagick Studio LLC Features: DPC Modules Delegates: bzlib freetype jng jpeg png xml zlib

ex1-clean.jpeg

magus commented Apr 3, 2014

Not experiencing the same results with the same example images.

⇨ convert -version Version: ImageMagick 6.8.6-3 2014-03-23 Q16 http://www.imagemagick.org Copyright: Copyright (C) 1999-2013 ImageMagick Studio LLC Features: DPC Modules Delegates: bzlib freetype jng jpeg png xml zlib

ex1-clean.jpeg

@richrines

This comment has been minimized.

Show comment
Hide comment
@richrines

richrines Apr 3, 2014

Unreal, well done.

Unreal, well done.

@lelandbatey

This comment has been minimized.

Show comment
Hide comment
@lelandbatey

lelandbatey Apr 3, 2014

@magnus The source images where actually higher resolution. Here's the first input image, and here's the second input image.

I don't know why github decided to display tiny, compressed versions in the gist summary.

Owner

lelandbatey commented Apr 3, 2014

@magnus The source images where actually higher resolution. Here's the first input image, and here's the second input image.

I don't know why github decided to display tiny, compressed versions in the gist summary.

@molven

This comment has been minimized.

Show comment
Hide comment
@molven

molven Apr 3, 2014

I tested the higher resolution example with 3 colors and can't find the result to be similar. The text, especially the red, does not look good. Did you use the same parameters when you made the examples above?

My result: http://espen.bagateller.com/whiteboardcleaner/1s.jpg
ImageMagick 6.7.7-10 2014-03-06 Q16

molven commented Apr 3, 2014

I tested the higher resolution example with 3 colors and can't find the result to be similar. The text, especially the red, does not look good. Did you use the same parameters when you made the examples above?

My result: http://espen.bagateller.com/whiteboardcleaner/1s.jpg
ImageMagick 6.7.7-10 2014-03-06 Q16

@ghost

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost Apr 3, 2014

Good work, thanks for sharing!

ghost commented Apr 3, 2014

Good work, thanks for sharing!

@FilterKaapi

This comment has been minimized.

Show comment
Hide comment
@FilterKaapi

FilterKaapi Apr 3, 2014

Wow! This is very good. I applied this to my first startup comic. Results are below.

Original: https://twitter.com/sanlaxman/status/450964599727083520/photo/1

Output: https://twitter.com/sanlaxman/status/451620563958505472/photo/1

Wow! This is very good. I applied this to my first startup comic. Results are below.

Original: https://twitter.com/sanlaxman/status/450964599727083520/photo/1

Output: https://twitter.com/sanlaxman/status/451620563958505472/photo/1

@mikaa123

This comment has been minimized.

Show comment
Hide comment
@mikaa123

mikaa123 Apr 3, 2014

Amazing work man!
Gonna try it soon and tell you how it turned out

mikaa123 commented Apr 3, 2014

Amazing work man!
Gonna try it soon and tell you how it turned out

@vibragiel

This comment has been minimized.

Show comment
Hide comment
@vibragiel

vibragiel Apr 3, 2014

I'm getting the same output as @molven with exactly the same ImageMagick version.

I'm getting the same output as @molven with exactly the same ImageMagick version.

@lelandbatey

This comment has been minimized.

Show comment
Hide comment
@lelandbatey

lelandbatey Apr 3, 2014

@molven, @vibragiel: Wow, I feel more than a bit ridiculous after looking into this. Turns out, those original examples I made using GIMP (same basic process, tuned the parameters to make it look nice). I'd originally put this gist together several months ago, and I hadn't done a thorough enough check before submitting to HN.

HOWEVER, I've since created new examples actually using the bash script, and the gist has been updated accordingly.

You can get these images here:

Input1
Input2

Output1
Output2

Owner

lelandbatey commented Apr 3, 2014

@molven, @vibragiel: Wow, I feel more than a bit ridiculous after looking into this. Turns out, those original examples I made using GIMP (same basic process, tuned the parameters to make it look nice). I'd originally put this gist together several months ago, and I hadn't done a thorough enough check before submitting to HN.

HOWEVER, I've since created new examples actually using the bash script, and the gist has been updated accordingly.

You can get these images here:

Input1
Input2

Output1
Output2

@xpepper

This comment has been minimized.

Show comment
Hide comment
@xpepper

xpepper Apr 3, 2014

Hi @lelandbatey, thanks for the idea.
I edited a bit your shell script whiteboardClean.sh to surround the two arguments ($1, $2) with double quotes, so that any space in the image path does not cause problem.

xpepper commented Apr 3, 2014

Hi @lelandbatey, thanks for the idea.
I edited a bit your shell script whiteboardClean.sh to surround the two arguments ($1, $2) with double quotes, so that any space in the image path does not cause problem.

@apetrov

This comment has been minimized.

Show comment
Hide comment
@apetrov

apetrov Apr 3, 2014

actually it would be easier to create a (z)sh function:
whiteboard () {
convert $1 -morphology Convolve DoG:15,100,0 -negate -normalize -blur 0x1 -channel RBG -level 60%,91%,0.1 $2
}

apetrov commented Apr 3, 2014

actually it would be easier to create a (z)sh function:
whiteboard () {
convert $1 -morphology Convolve DoG:15,100,0 -negate -normalize -blur 0x1 -channel RBG -level 60%,91%,0.1 $2
}

@SNaushadS

This comment has been minimized.

Show comment
Hide comment
@SNaushadS

SNaushadS Apr 3, 2014

This is simple and effective. Many such photos ive taken lie unattended. Now i can clean them up and save.

This is simple and effective. Many such photos ive taken lie unattended. Now i can clean them up and save.

@artumi-richard

This comment has been minimized.

Show comment
Hide comment
@artumi-richard

artumi-richard Apr 3, 2014

The output files are suitable for png optimisation, using something like pngquant

http://pngquant.org/

On Output1 and Output2 the pngquant defaults got the file sizes to 42% and 38% of the original sizes respectively.

The output files are suitable for png optimisation, using something like pngquant

http://pngquant.org/

On Output1 and Output2 the pngquant defaults got the file sizes to 42% and 38% of the original sizes respectively.

@marcaube

This comment has been minimized.

Show comment
Hide comment
@marcaube

marcaube Apr 3, 2014

I would've loved this when I was in college! So much note-taking and so little listening ...

marcaube commented Apr 3, 2014

I would've loved this when I was in college! So much note-taking and so little listening ...

@rylwin

This comment has been minimized.

Show comment
Hide comment

rylwin commented Apr 4, 2014

awesome

@silvansky

This comment has been minimized.

Show comment
Hide comment
@silvansky

silvansky Apr 4, 2014

Please, add quotes around $1 and $2 to support long file names in your great script! =)

Please, add quotes around $1 and $2 to support long file names in your great script! =)

@bensquire

This comment has been minimized.

Show comment
Hide comment
@bensquire

bensquire Apr 4, 2014

Works a treat :D

Works a treat :D

@Intrepidd

This comment has been minimized.

Show comment
Hide comment
@Intrepidd

Intrepidd Apr 4, 2014

It's also nice for selfies :)

http://i.imgur.com/uHoPvin.jpg

It's also nice for selfies :)

http://i.imgur.com/uHoPvin.jpg

@ff-apujari

This comment has been minimized.

Show comment
Hide comment
@ff-apujari

ff-apujari Apr 4, 2014

great stuff, I just added to my bashrc

white-board-cleaner () { convert $1 -morphology Convolve DoG:15,100,0 -negate -normalize -blur 0x1 -channel RBG -level 60%,91%,0.1 $2; }

great stuff, I just added to my bashrc

white-board-cleaner () { convert $1 -morphology Convolve DoG:15,100,0 -negate -normalize -blur 0x1 -channel RBG -level 60%,91%,0.1 $2; }

@statico

This comment has been minimized.

Show comment
Hide comment
@statico

statico Apr 4, 2014

If you want to make an AppleScript droplet on Mac OS X, paste this into a new script and save it as an application:

on open thefiles
  repeat with thefile in thefiles
    set finalpath to POSIX path of thefile
    do shell script "mktemp -t image"
    set temppath to the result
    set success to false
    try
      do shell script "/usr/local/bin/convert '" & finalpath & "' -morphology Convolve DoG:15,100,0 -negate -normalize -blur 0x1 -channel RBG -level 60%,91%,0.1 '" & temppath & "'"
      set success to true
    on error theerror
      display dialog "Conversion failed: " & theerror
    end try
    if success then
      do shell script "mv '" & temppath & "' '" & finalpath & "'"
      display notification "Converted " & finalpath
    end if
  end repeat
end open

statico commented Apr 4, 2014

If you want to make an AppleScript droplet on Mac OS X, paste this into a new script and save it as an application:

on open thefiles
  repeat with thefile in thefiles
    set finalpath to POSIX path of thefile
    do shell script "mktemp -t image"
    set temppath to the result
    set success to false
    try
      do shell script "/usr/local/bin/convert '" & finalpath & "' -morphology Convolve DoG:15,100,0 -negate -normalize -blur 0x1 -channel RBG -level 60%,91%,0.1 '" & temppath & "'"
      set success to true
    on error theerror
      display dialog "Conversion failed: " & theerror
    end try
    if success then
      do shell script "mv '" & temppath & "' '" & finalpath & "'"
      display notification "Converted " & finalpath
    end if
  end repeat
end open
@didymu5

This comment has been minimized.

Show comment
Hide comment
@didymu5

didymu5 Apr 4, 2014

this is so cool! i'm going to introduce my wife to this.

didymu5 commented Apr 4, 2014

this is so cool! i'm going to introduce my wife to this.

@kinduff

This comment has been minimized.

Show comment
Hide comment
@kinduff

kinduff Apr 4, 2014

@lelandbatey Good job, bro!

If you guys want to convert that output png to a svg vector format, you can use AutoTrace to archive this.

I'm currently using the following command with these options, if you find a better solution, please post it here :)

./autotrace \
  --dpi 1024 \
  --line-threshold 0.1 \
  --color-count 16 \
  --corner-always-threshold 60 \
  --line-reversion-threshold 0.1 \
  --width-weight-factor 0.1 \
  --despeckle-level 10 \
  --despeckle-tightness 5 \
  --preserve-width \
  --remove-adjacent-corners \
  --output-format svg \
  --output-file out.svg \
  in.png

in.png
out.svg

kinduff commented Apr 4, 2014

@lelandbatey Good job, bro!

If you guys want to convert that output png to a svg vector format, you can use AutoTrace to archive this.

I'm currently using the following command with these options, if you find a better solution, please post it here :)

./autotrace \
  --dpi 1024 \
  --line-threshold 0.1 \
  --color-count 16 \
  --corner-always-threshold 60 \
  --line-reversion-threshold 0.1 \
  --width-weight-factor 0.1 \
  --despeckle-level 10 \
  --despeckle-tightness 5 \
  --preserve-width \
  --remove-adjacent-corners \
  --output-format svg \
  --output-file out.svg \
  in.png

in.png
out.svg

@LucasArruda

This comment has been minimized.

Show comment
Hide comment

Amazing!

@LucasArruda

This comment has been minimized.

Show comment
Hide comment

Amazing!

@anthonyray

This comment has been minimized.

Show comment
Hide comment
@anthonyray

anthonyray Apr 5, 2014

That's great !

That's great !

@sourcegate

This comment has been minimized.

Show comment
Hide comment
@sourcegate

sourcegate Apr 8, 2014

Just wanted to say thanks for sharing was super useful for me. I'm always doing these in Photoshop and this is a huge time saver for me.

Just wanted to say thanks for sharing was super useful for me. I'm always doing these in Photoshop and this is a huge time saver for me.

@gsdean

This comment has been minimized.

Show comment
Hide comment
@ShivendraAgrawal

This comment has been minimized.

Show comment
Hide comment
@ShivendraAgrawal

ShivendraAgrawal Apr 10, 2014

Could somebody help me with identification of the image processing algorithms used? And the order in which they were used?

Could somebody help me with identification of the image processing algorithms used? And the order in which they were used?

@captainpete

This comment has been minimized.

Show comment
Hide comment
@captainpete

captainpete May 6, 2014

Incredible!!

Incredible!!

@delegans

This comment has been minimized.

Show comment
Hide comment
@delegans

delegans May 7, 2014

Web service: upload and clean white board on-line

http://api.o2b.ru/whiteboardcleaner

delegans commented May 7, 2014

Web service: upload and clean white board on-line

http://api.o2b.ru/whiteboardcleaner

@m-space

This comment has been minimized.

Show comment
Hide comment
@m-space

m-space May 16, 2014

For anyone stuck on a Windows platform, you can save this slightly modified version to whiteboardClean.bat:

convert %1 -morphology Convolve DoG:15,100,0 -negate -normalize -channel RBG -level 60%%,91%%,0.1 %2

You can further improve the batch file to loop over multiple image files. Usage: batchClean.bat *.jpg

FOR %%A IN (%*) DO (
    convert %%A -morphology Convolve DoG:15,100,0 -negate -normalize -channel RBG -level 60%%,91%%,0.1 cln_%%A
)

m-space commented May 16, 2014

For anyone stuck on a Windows platform, you can save this slightly modified version to whiteboardClean.bat:

convert %1 -morphology Convolve DoG:15,100,0 -negate -normalize -channel RBG -level 60%%,91%%,0.1 %2

You can further improve the batch file to loop over multiple image files. Usage: batchClean.bat *.jpg

FOR %%A IN (%*) DO (
    convert %%A -morphology Convolve DoG:15,100,0 -negate -normalize -channel RBG -level 60%%,91%%,0.1 cln_%%A
)
@greywolve

This comment has been minimized.

Show comment
Hide comment
@greywolve

greywolve Jul 20, 2014

Thank you! Works great :)

Thank you! Works great :)

@projectdevan

This comment has been minimized.

Show comment
Hide comment
@projectdevan

projectdevan Jan 17, 2015

Checkout this new service http://www.brightboard.co.in/ . It is pretty basic and non secure now and is in devel mode. Started it as a new service. Help to make it better by giving your suggestions

Checkout this new service http://www.brightboard.co.in/ . It is pretty basic and non secure now and is in devel mode. Started it as a new service. Help to make it better by giving your suggestions

@mburr

This comment has been minimized.

Show comment
Hide comment
@mburr

mburr Aug 10, 2015

Thank you so much for posting the one liner - my own little bit of monkeying around didn't work well. This does a great job!

mburr commented Aug 10, 2015

Thank you so much for posting the one liner - my own little bit of monkeying around didn't work well. This does a great job!

@peterjamesbaldwin-myob

This comment has been minimized.

Show comment
Hide comment

Great work.

@amn41

This comment has been minimized.

Show comment
Hide comment
@amn41

amn41 Sep 14, 2016

@lelandbatey any tips on fixing the way the text looks here? http://imgur.com/a/dWddi I thought it was maybe bc I fed it a jpg but I converted to png & still get blurry / hard-to-read text

amn41 commented Sep 14, 2016

@lelandbatey any tips on fixing the way the text looks here? http://imgur.com/a/dWddi I thought it was maybe bc I fed it a jpg but I converted to png & still get blurry / hard-to-read text

@mickdee

This comment has been minimized.

Show comment
Hide comment
@mickdee

mickdee Nov 29, 2016

When trying to run the same command in the readme on Mac Sierra I get the following error (I have a test image in the same directory from which I'm running the command):

convert: unable to load module `/usr/local/Cellar/imagemagick/6.8.9-1/lib/ImageMagick//modules-Q16/coders/jpeg.la': file not found @ error/module.c/OpenModule/1282.
convert: no decode delegate for this image format `JPEG' @ error/constitute.c/ReadImage/501.
convert: no images defined `imageclean.png' @ error/convert.c/ConvertImageCommand/3187.

mickdee commented Nov 29, 2016

When trying to run the same command in the readme on Mac Sierra I get the following error (I have a test image in the same directory from which I'm running the command):

convert: unable to load module `/usr/local/Cellar/imagemagick/6.8.9-1/lib/ImageMagick//modules-Q16/coders/jpeg.la': file not found @ error/module.c/OpenModule/1282.
convert: no decode delegate for this image format `JPEG' @ error/constitute.c/ReadImage/501.
convert: no images defined `imageclean.png' @ error/convert.c/ConvertImageCommand/3187.
@bruceathome

This comment has been minimized.

Show comment
Hide comment
@bruceathome

bruceathome Oct 17, 2017

Hi. Blatant ask for assistance - is there any way to get a similar script to run in python (actually pythonista on an ipad)? My students (high school) send me photographs of their responses to questions. I then save these on my iPad and use a script? in the 'workflow' app which rotates the images (if necessary) and converts them to pdf, which I then open in another app (notability) so that I can annotate and then email them back to the students. I would like to use the above script as part of my workflow script to automate everything. My thoughts are to use pythonista (which 'workflow' can talk to) to run something similar to the script above to clean up the students photographs. Sorry for the long-winded ask for help (non-programmer here).

Hi. Blatant ask for assistance - is there any way to get a similar script to run in python (actually pythonista on an ipad)? My students (high school) send me photographs of their responses to questions. I then save these on my iPad and use a script? in the 'workflow' app which rotates the images (if necessary) and converts them to pdf, which I then open in another app (notability) so that I can annotate and then email them back to the students. I would like to use the above script as part of my workflow script to automate everything. My thoughts are to use pythonista (which 'workflow' can talk to) to run something similar to the script above to clean up the students photographs. Sorry for the long-winded ask for help (non-programmer here).

@henrebotha

This comment has been minimized.

Show comment
Hide comment
@henrebotha

henrebotha May 22, 2018

@bruceathome did you manage? I can try and help you. Drop me an email (address here https://github.com/henrebotha).

@bruceathome did you manage? I can try and help you. Drop me an email (address here https://github.com/henrebotha).

@Bersaelor

This comment has been minimized.

Show comment
Hide comment
@Bersaelor

Bersaelor May 24, 2018

Next step:
Replicate same line with CIFilters and put it in an app, so you don‘t have to export them to PC first.

Next step:
Replicate same line with CIFilters and put it in an app, so you don‘t have to export them to PC first.

@luisDVA

This comment has been minimized.

Show comment
Hide comment
@luisDVA

luisDVA Jun 2, 2018

has anyone here used this workflow in the 'magick' package in R?
I can't replicate the last bit because I can't figure out how the -level operator was implemented

luisDVA commented Jun 2, 2018

has anyone here used this workflow in the 'magick' package in R?
I can't replicate the last bit because I can't figure out how the -level operator was implemented

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment