Replace pixels in an image with another image - image

I want to replace the black pixel of (image 1) with another image so the result looks like image 2
Image 1
http://imgur.com/xCLqxbi
Image 2 (result)
http://imgur.com/ALiX0fU
Is there a way to manage this with pref PHP or Javascript?

Sure, I am doing it with the commandline of Imagemagick, but there are PHP bindings available too. ImageMagick is installed in most Linux distors and available for Windows and OS X.
The command is this:
convert base.gif wallpaper.png -fx "u.r<0.1 && u.g<0.1 &&u.b<0.1? v : u" out.png
using your base image and some wallpaper from another question I answered.
Basically, the -fx operator allows you to do your own processing. So, I say if the red channel of the original image is less than 10% (i.e. really dark), and the green and the blue, replace the pixel with the corresponding pixel from the second image (wallpaper). The pixels of te first image are referrred to as u and those of the second image (wallpaper) as v. So u.r refers to the red component of the first image's pixels.
You can get a little fancier and avoid outliers and lonely pixels like under the fridge door and at the bottom left of the back wall on the carpet. Here I introduce a third image into the processing that is a copy of the original, but I then threshold it and median filter to reduce outliers. The first line of the command corresponds to the base image, the second line refers to the filtered base image and the third to the wallpaper. I now refer to the pixels of the base image as u[0], those of the filtered base image as u[1] and those of the wallpaper as u[2].
convert base.gif \
\( base.gif -depth 8 -threshold 1 -median 3x3 \) \
wallpaper.png \
-fx "u[1].r==0.0 ? u[2]:u[0]" \
out.png
You may find the -fx operator slow if you have lots of images to do, so you could proceed like this instead. First make a nice mask of the black areas by thresholding and median filtering to remove outliers.
convert base.gif -depth 8 -threshold 1 -median 3x3 -negate mask.png
Now take the wallpaper and mask its opacity with the mask, then composite the result over the base image:
convert wallpaper.png \
mask.png \
-compose copyopacity -composite \
base.gif \
-compose dstover -composite \
result.png

Related

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

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.

Binarize an image

I am sorry for image sizes.
Now these two cropped images I have in a dataset.
I am going to feed these images into a machine learning algorithm.
Before doing that, I want to extract binarized digits and feed the binary images into algorithm, instead of feeding directly. Can you please elaborate how can I achieve this kind of clean binarization ?
I found otsu and other thresholding methods but they were unable to give clear digits in image.
I had some success, though I don't know how it will fare with the rest of your images, using a 2-colour quantisation, conversion to greyscale and normalisation.
I just did it at the command line with ImageMagick, as follows:
convert input.png +dither -colors 3 -colors 2 -colorspace gray -normalize -scale 250x result.png
So, it loads an image and disables dithering, so that the subsequent quantisation only results in 2 actual colours rather than dithered mixtures. I then quantise down to 3 colours - still in RGB colourspace - and then further down to 2 colours. Then, I convert those 2 colours to greyscale and normalise them so the darker one becomes black and the lighter one becomes white.
An alternate approach, to what Mark Setchell suggested, in ImageMagick goes over to OpenCv rather straightforward. OpenCV has adaptive thresholding see https://docs.opencv.org/3.3.1/d7/d4d/tutorial_py_thresholding.html and connected components processing see https://docs.opencv.org/3.1.0/d3/dc0/group__imgproc__shape.html#gac2718a64ade63475425558aa669a943a and https://www.pyimagesearch.com/2016/10/31/detecting-multiple-bright-spots-in-an-image-with-python-and-opencv/
1) convert to grayscale
2) stretch image to full dynamic range
3) apply local (adaptive) thresholding
4) optionally use connected components labelling to remove regions smaller than some total number of pixels (area).
convert 2.png \
-colorspace gray \
-auto-level \
-lat 20x20+10% \
2_lat.gif
convert 19.png \
-colorspace gray \
-auto-level \
-negate \
-lat 20x20+5% \
19_lat.gif
Do optional connected components processing here:
convert 2_lat.gif \
-define connected-components:area-threshold=40 \
-define connected-components:mean-color=true \
-connected-components 4 \
2_lat_ccl.gif
convert 19_lat.gif \
-define connected-components:area-threshold=20 \
-define connected-components:mean-color=true \
-connected-components 4 \
19_lat_ccl.gif
To smooth the images, you would likely need to use a raster to vector tool such as potrace.

How to blur/pixelate part of an image using ImageMagick?

I am using Perl and ImageMagick (Perl-API).
In a first step i would like to take a rectangle of an image and blur this part of the image. Desired result is the original image with the rectangle blured.
In a second step i need to blur a part of an image with a turned rectangle (i.e. turned by 35%).
How can i achieve this?
Best way I can think of is to leverage masks to blur against. This would allow you to "draw" a shape, and pass through what to be blurred.
Example:
# Create base image
convert rose: -sample 200x rose_large.png
# Create mask
convert -size 200x131 xc:black -fill white -draw 'circle 100 65 100 25' rose_mask.png
# Blur with mask
convert rose_large.png -mask rose_mask.png -blur 0x8 +mask rose_blur_mask.png
Other techniques and examples here. I'm not familiar with Perl API, but there should be a Mask method that accepts an image handler parameter.
Update
For rectangle, you would simply update the shape to draw on the mask. Here's an example where I'm only blur-ing what's inside a rectangle.
# Create rectangle mask
convert -size 200x131 xc:white -fill black -draw 'rectangle 50 30 150 100' rose_rectangle_mask.png
# And repeat blur apply
convert rose_large.png -mask rose_rectangle_mask.png -blur 0x8 +mask rose_blur_retangle_mask.png
As you asked for PerlMagick, I pulled my last few remaining hairs out to try and do this in Perl... the files 1.png, 2.png and 3.png are purely for debug so you can see what I am doing.
#!/usr/bin/perl
use strict;
use warnings;
use Image::Magick;
my $x;
my $image;
my $blurred;
my $mask;
# Create original fishscale image
$image=Image::Magick->new(size=>'600x300');
$image->Read('pattern:fishscales');
$image->Write(filename=>"1.png");
# Copy original image and blur
$blurred = $image->Clone();
$blurred->GaussianBlur('x2');
$blurred->Write(filename=>"2.png");
# Make mask and rotate
$mask=Image::Magick->new(size=>'600x300');
$mask->Read('xc:white');
$mask->Draw(fill=>'black',primitive=>'rectangle',points=>'100,100,200,200');
$mask->Set('virtual-pixel'=>'white');
$mask->Rotate(20);
$mask->Transparent('white');
$mask->Write(filename=>"3.png");
# Copy mask as alpha channel into blurred image
$blurred->Composite(image=>$mask,qw(compose CopyOpacity gravity center));
# Composite blurred image onto original
$image->Composite(image=>$blurred);
$image->Write(filename=>'result.png');
Here are the debug images...
1.png
2.png
3.png
result.png
There may be a much faster, simpler, more efficient way of doing this, but I don't know it, and there are precious few examples of PerlMagick out there, so I'll stick my marker in the sand and see if anyone can better it:-)
P.S. Don't feel bad about my hair - there were only three left anyway :-)

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.

“Diff” an image using ImageMagick

How can I get the difference between two images? I have the original image. Someone has written on an exact duplicate of the original image. Now, I need to compare the original to the written on image and extract just the writing in image format.
Example: I have a picture of a house. Someone took a copy and wrote “Hello!” on the copy. I want to somehow compare the two pictures, remove the house, and be left with an image of the words “Hello!”.
Is this possible with ImageMagick? I know there are ways to get the statistical difference between images, but that is not what I am looking for.
My own favorites are these two:
compare image1 image2 -compose src diff.png
compare image1 image2 -compose src diff.pdf
The only difference between the 2 commands above: the first one shows the visual difference between the two images as a PNG file, the second one as a PDF.
The resulting diff file displays all pixels which are different in red color. The ones which are unchanged appear white.
Short and sweet.
Note, your images need not be the same type. You can even mix JPEG, TIFF, PNG -- under one condition: the images should be of the same size (image dimension in pixels). The output format is determined by the output filename's extension.
Should you, for some reason, need a higher resolution than the default one (72 dpi) -- then just add an appropriate -density parameter:
compare -density 300 image1 image2 -compose src diff.jpeg
Illustrated examples
Here are a few illustrations of results for variations of the above command. Note: the two files compared were even PDF files, so it works with these too (as long as they are 1-pagers)!
Left: Image with text Center: Original image Right: Differences (=text) in red pixels.
compare \
porsche-with-scratch.pdf porsche-original.pdf \
-compose src \
diff-compose-default.pdf
This is the same command I suggested earlier above.
Left: Image with text Center: Original image Right: Differences in 'seagreen' pixels.
compare \
porsche-with-scratch.pdf porsche-original.pdf \
-compose src \
-highlight-color seagreen \
diff-compose-default.pdf
This command adds a parameter to make the difference pixels 'seagreen' instead of the default red.
Left: Image with text Center: Original image Right: Blue diffs (but w. some context background)
l
compare \
porsche-with-scratch.pdf porsche-original.pdf \
-highlight-color blue \
diff-compose-default.pdf
This command removes the -compose src part -- the result is the default behavior of compare which keeps as a lightened background the first one of the 2 diffed images. (This time with added parameter to make the diff pixels appear in blue.)
While compare does a good job for many applications, I found that sometimes I prefer a different approach, particularly when comparing images which are mostly grayscale:
convert '(' file1.png -flatten -grayscale Rec709Luminance ')' \
'(' file2.png -flatten -grayscale Rec709Luminance ')' \
'(' -clone 0-1 -compose darken -composite ')' \
-channel RGB -combine diff.png
The idea is follows: convert both file1.png and file2.png to grayscale. Then trat the first as the red channel of the resulting image, the second as the green channel. The blue channel is formed from these two using the darken compose operator, which essentially means taking the minimum.
So things which are white in both images stay white. Things which are black in both images stay black. Things which are white in the first image but black in the second turn red, and things which are white in the second but black in the first turn green.
The result gives you a nicely color-coded image where you can easily associate green with the first input and red with the second. Here is an example where I'm using this to compare the output from LaTeX against that from KaTeX (before I fixed some bug to make this better):
You can combine the approaches, using compare to see where something changed and then using the above to see in more detail how it changed.
From ImageMagick 6.3.4, you can use -compose ChangeMask (see also "Removing a Known Background" and following sections).
For example, using IM7 and these images stone.png, diamond_ore.png, and netherrack.png:
magick diamond_ore.png stone.png -fuzz 15% -compose ChangeMask -composite diamond_ore_overlay.png gives:
magick netherrack.png \( diamond_ore.png stone.png -fuzz 15% -compose ChangeMask -composite +compose \) -composite nether_diamond_ore.png gives:

Resources