How to give an image an old, dusty appearance with faded colours? - image

I have images of old paintings. The paintings are old and dusty with faded colours as shown here.
How do I give any image this type of an 'old' appearance? I couldn't find any filters or openCV functions to achieve this type of look?
EDIT: My question is different as the other one solves the problem using the sepia filter and using the grain effect. I'm not looking for that sort of an appearance. I want my image to look like an old damaged painting. This means that the colours should be faded and it should have an overall dusty appearance.

There's no real need to write any code and use OpenCV, since you can do all that on the command-line with ImageMagick which is installed on most Linux distros and is available for macOS and Windows.
First, fading. This can be simulated by reducing the saturation of an image. So if we start with this Mona Lisa image:
We can fade her using this command to leave the brightness unchanged at 100% of its original value and reduce the saturation to 50% of its original value. I am intentionally "over-egging" everything so you can see it clearly. You should maybe be more subtle.
convert mona.jpg -modulate 100,50 result.jpg
Next, vignetting - or dark corners. You can use something like this:
convert mona.jpg \
\( +clone -fill white -colorize 100 -background "gray(50%)" -vignette 0x15+1+1% \) \
-compose multiply -composite result.jpg
The 0x15 controls the roll-off, or how gradual the change is, so increase the 0x15 if you want a smoother roll-off or go down to 0x5 if you want it harder. The +1+1% means that the ellipse will be 1% smaller than the width of the image and 1% smaller than the height of the image. So if you want a smaller light hole and bigger dark corners, go for +10+10%. The degree of darkening is controlled by the gray(50%) so you can diddle with that till you are happy too :-)
Finally, dust. Best thing is to get a PNG image of some dust, resize it to match the size of your image and overlay it.
First get the size of Mona:
identify mona.jpg
mona.jpg JPEG 403x600 403x600+0+0 8-bit sRGB 57130B 0.000u 0:00.000
So, she is 403x600. Here is a sample of some dust - again, you can be more subtle - I am just being heavy-handed so it shows:
Let's resize the dust to match and overlay it:
convert mona.jpg \( dust.png -resize 403x600\! \) -composite result.jpg
Then you can combine all three effects, fading, vignetting and dust, into a single command:
convert mona.jpg -modulate 100,50% \
\( +clone -fill white -colorize 100 -background "gray(50%)" -vignette 0x15+1+1% \) \
-compose multiply -composite \
\( dust.png -resize 403x600\! \) -composite result.jpg
If you have lots of images to process, you can script the whole lot to be done in parallel very easily with GNU Parallel - see some of my other answers for examples.
Keywords: artificial ageing, image ageing, command-line, command line, ImageMagick, magick, old, old photo, photo effect, convert, dust, scratches, fading, faded.

I would suggest using a style transfer tool, rather than manually coming up with a procedure to mimic the style of an old painting. There are plenty free style transfer tools and libraries available.

I would suggest using OpenCV various filters to create the effect you need. You have to try various filters and try to figure what works for you, But I have suggestions which you can try.
For color, fading try Erode and Dilate with small kernel size.
Next, add some noise, Salt and Pepper will do just fine, also try gaussian filter after applying noise. Salt and Pepper is non-linear noise and Gaussian is a linear filter so it will just spread the noise, but keep the filter kernel small.
Try finding some images of dust, torn page edges (WITHOUT BACKGROUND) like in the following link:
https://www.google.co.in/searchq=dust+png+images&newwindow=1&rlz=1C1CHBF_enIN797IN798&source=lnms&tbm=isch&sa=X&ved=0ahUKEwjtq7ZvfPcAhXJO48KHQ2UD0kQ_AUICigB&biw=1536&bih=759#imgrc=_
Keeping alpha transparency in mind, mask these over your images.
With all the things in correct proportion and sequence, You will get your old dusty image.

Related

Imagick: Return position and size of circular objects in image

I have this image:
Using this Imagick cli command:
magick model.png -canny 0x0+1%+10% -negate -blur 3x.7 -solarize 50% -level 50%,0 model_canny.png
it got converted to this :
is it possible to get the position/size of the teeth in the arch? it doesn't have to be perfect. Even if it detects few teeth in the arch it would be a great for me to understand how this works. So far I've tried to use connected-components param and it gives me thousands of results which is obviously incorrect. Here's what I've done so far:
magick model_canny.png -fuzz 5% -define connected-components:verbose=true -connected-components 4 objects.png
Also is it possible to remove the random black lines inside the teeth? Any help would be appreciated..
The usual way to separate objects is to use a morphological erosion, using a command something like this:
magick fangs.png -alpha extract -trim -morphology erode disk:5 result.png
Here is an animation of the effect of various disk sizes:
Taking that a bit further, you could maybe erode in a loop and then do a "Connected Component Analysis" and count the blobs, and keep increasing the disk size till you get a sensible number of teeth.
Or, you may need to work a bit harder and try to fit a parabola (shown in blue) to the pixels that make up the teeth if that is the best shape - not a dentist, myself! Then, with a parabola, you could find the normals to the parabola (shown in red) all the way around and take the normal that crosses the smallest amount of tooth as the boundary between the teeth. Rough diagram:
Or maybe superimpose your Canny edge-detected image on the fitted parabola, and see where your edges intersect with it.

Compressing an image to make it less than 4KB

I have an image of a person and I want to compress it to make it less than 4KB. I need to compress it and still have the face of the person recognizable even if the image will shrink.
Here is Theresa May at 142kB:
and resized to 72x72 and converted to greyscale and reduced to 2kB with ImageMagick at the command line:
convert original.jpg -resize 72x72 -colorspace gray -define jpeg:extent=2kb result.jpg
I can still recognise her.
Here is some other guy reduced to 1kB and I can still recognise him too:
ImageMagick is installed on most Linux distros and is available for macOS and Windows. Bindings are available for Python, PHP, Ruby, Javascript, Perl etc.
If you had further knowledge about your images, or your recognition algorithm, you may be able to do better. For example, if you knew that the centre of the image was more important than the edges, you could slightly blur, or reduce contrast in relatively unimportant areas and use the available space for more details in the important areas.
Mark Setchell has the right idea. But I might suggest one potential minor improvement. Remove any meta data including profiles, EXIF data etc. You can do that by either adding -strip
convert input.jpg -strip -resize 72x72 -colorspace gray -define jpeg:extent=2kb result.jpg
or by using -thumbnail rather than -resize. The former automatically does the strip.
convert input.jpg -thumbnail 72x72 -colorspace gray -define jpeg:extent=2kb result.jpg

imagemagick gradient mask file creation

I'm playing with this creative script here: http://www.fmwconcepts.com/imagemagick/transitions/. The plan is to mimic what happens with the script with ffmpeg and generate video with transition effects between pictures. My current understanding is this:
I have two pictures A and B.
I need in between a couple of pictures (say 15) that are partially A and partially B.
To do that I use the composite -compose src-over A.jpg B.jpg mask-n.jpg out.jpg command.
During the process, the mask-n.jpg gets generated automatically that gradually change from all black to all white.
Depends on the mathematically equations, the way the transition effect looks is different.
In one of the example, Fred the author gave this:
convert -size 128x128 gradient: maskfile.jpg
This will generate a image like this:
This is partially black and partially white. For the transition to work, I'll need an all white one and an all black one and a couple of others in between. What's the magical command to do that?
I have re-read your question and I am still not sure I understand, but maybe you want a dark grey to light grey gradient:
convert -size 128x128 gradient:"rgb(40,40,40)-rgb(200,200,200)" greygrad.png
Not sure I understand what you are trying to achieve, but if you want an all black one, use:
convert -size 128x128 xc:black black.jpg
and an all white one:
convert -size 128x128 xc:white white.jpg
and a grey one:
convert -size 128x128 xc:gray40 gray40.jpg
If you want to join them for transitions, use
convert im1.jpg im2.jpg -append result.jpg
or use +append to join side by side instead of above and below.
Consider using PNG instead of JPEG throughout.
Fred tells you how the script works at the bottom of the page you have linked to with some example code.
According to his explanation there is only the one mask images as:
The mask images is gradually made lighter

Change Pixel Values of Image to remove Date

What is the most efficient technique to remove the date that a Camera embeds on any image it takes.
The task is to prepare a script/code/software that shall remove the date from the given input image file (jpeg, png).
Please let me know an optimum way to accomplish this.
Thank you.
Here is an alternative approach to the question. You can determine the average colour of the bottom right corner of the image (size 250px wide x 100px high) with Imageagick like this:
ave=$(convert sign.jpg -gravity southeast -crop 250x100+0+0 -scale 1x1 -format "%[pixel:p{0,0}]" info:)
That will give you the value srgb(199,181,119) for this image. Now you can create a rectangle (200px x 50px) that colour and overlay it onto the image and then blur the edges a little to blend it in:
convert sign.jpg \( -size 200x50 xc:"$ave" \) -geometry +970+780 -composite -region 240x90+950+760 -blur 0x10 out.jpg
I am not sure if you were hoping for something that is forensically indetectable or something that more or less removes the distraction somewhat. Hopefully the latter :-)
A little measuring around shows that the date is located at the following position:
150x40+650+520
i.e. 150 pixels wide by 40 pixels high, located 650 pixels to the right of the top left corner and 520 pixels down from the top left corner.
So, one approach would be to copy the piece of the image directly below that, and paste it on top of the date, which can be done in ImageMagick in one command like this:
convert sign.jpg \( +clone -crop 150x40+650+560 +repage \) -geometry +650+520 -composite out.jpg
That says... take the original image and create a copy of it (+clone), then cut out the piece specified after the crop command command and reset that as though it was the top left corner (+repage). Then paste (-composite) that image at offset +650+520 on top of the original image and save the result as out.jpg.
It is not a beautifully engiineered solution, but may be good enough. It may be desirable to blur the area a little, to help disguise it. Alternatively, it may be possible to select the colours within the date and make them transparent, then to displace the original image a little behind the transparent holes to fill them - I didn't choose that option because it is harder and because you may not like ImageMagick anyway, and there are actually several colours within the date field ranging from browns to golden yellows and selecting them without affecting the remainder of the image might start getting fun!
ImageMagick is free and available for Windows, OSX, Linux etc from here. It is ready installed on most Linux distros anyway.

Remove background color in image processing for OCR

I am trying to remove background color so as to improve the accuracy of OCR against images. A sample would look like below:
I'd keep all letters in the post-processed image while just removing the light purple color textured background. Is it possible to use some open source software such as Imagemagick to convert it to a binary image (black/white) to achieve this goal? What if the background has more than one color? Would the solution be the same?
Further, what if I also want to remove the purple letters (theater name) and the line so as to only keep the black color letters? Simple cropping might not work because the purple letters could appear at other places as well.
I am looking for a solution in programming, rather than via tools like Photoshop.
You can do this using GIMP (or any other image editing tool).
Open your image
Convert to grayscale
Duplicate the layer
Apply Gaussian blur using a large kernel (10x10) to the top layer
Calculate the image difference between the top and bottom layer
Threshold the image to yield a binary image
Blurred image:
Difference image:
Binary:
If you're doing it as a once-off, GIMP is probably good enough. If you expect to do this many times over, you could probably write an imagemagick script or code up your approach using something like Python and OpenCV.
Some problems with the above approach:
The purple text (CENTURY) gets lost because it isn't as contrasting as the other text. You could work your way around it by thresholding different parts of the image differently, or by using local histogram manipulation methods
The following shows a possible strategy for processing your image, and OCR it
The last step is doing an OCR. My OCR routine is VERY basic, so I'm sure you may get better results.
The code is Mathematica code.
Not bad at all!
In Imagemagick, you can use the -lat function to do that.
convert image.jpg -colorspace gray -negate -lat 50x50+5% -negate result.jpg
convert image.jpg -colorspace HSB -channel 2 -separate +channel \
-white-threshold 35% \
-negate -lat 50x50+5% -negate \
-morphology erode octagon:1 result2.jpg
You can apply blur to the image, so you get almost clear background. Then divide each color component of each pixel of original image by the corresponding component of pixel on the background. And you will get text on white background. Additional postprocessing can help further.
This method works in the case if text is darker then the background (in each color component). Otherwise you can invert colors and apply this method.
If your image is captured as RGB, just use the green image or quickly convert the bayer pattern which is probably #misha's convert to greyscale solutions probably do.
Hope this helps someone
Using one line code you can get is using OpenCV and python
#Load image as Grayscale
im = cv2.imread('....../Downloads/Gd3oN.jpg',0)
#Use Adaptivethreshold with Gaussian
th = cv2.adaptiveThreshold(im,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)
Here's the result
Here's the link for Image Thresholding in OpenCV

Resources