Can offset x but not y when converting image - imagemagick-convert

Here's the overview of the problem. I want to crop an image to get a rectangle that is down a little and to the right a little. Somehow I can only set the x coordinate of the upper-left of the image. I can't get it to set the y coordinate of that rectangle - the upper part is always at the top.
Here's what the original image looks like. I can't post the actual original image because it's too large to upload. You can download the original image here.
Here's the command I use to convert to a subset of that image:
/usr/bin/convert ./med.jpeg -crop 30%x12+300x50 ./ul.jpg
Which produces this image:
As you can see, it does a good job of offsetting the x axis, but it won't offset the y axis. The rectangle always starts at the top of the original image, no matter value I set at the end of the crop geometry.
So what am I missing here?
Here's the version of convert:
# convert -version
Version: ImageMagick 6.9.10-23 Q16 x86_64 20190101 https://imagemagick.org
Copyright: © 1999-2019 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC Modules OpenMP
Delegates (built-in): bzlib djvu fftw fontconfig freetype jbig jng jpeg lcms lqr ltdl lzma openexr pangocairo png tiff webp wmf x xml zlib
Any help is appreciated.

You have a simple typo in your ImageMagick command. You have put x in place of + between the X and Y offsets. Both must have either + or - not x.
You have
30%x12+300x50
and it should be
30%x12+300+50

Related

Convert Color image to grayscale image using Octave

I have a color image that I'm trying to convert to grayscale, but I get an error:
warning: the 'rgb2gray' function belongs to the image package from Octave Forge but has not yet been implemented
I'm using Octave 4.2.2 on Ubuntu 18.04 64-bit and can't upgrade this version to Octave 5.1 yet.
Is there a workaround?
My goal is:
To convert a color image into grayscale.
Then place the intensity/brightness of each grayscale pixel into a range between 0-1.
My code:
pkg load image
% read image from url (I took a random image on internet)..
[url_img, map] = imread('http://i.imgur.com/9PDZb7i.png');
figure, imshow(url_img), title('Image from url')
% resize it..
resized_img1 = imresize(url_img, 0.2); % resize by a factor here 0.2
resized_img2 = imresize(url_img, [600 500]); % resize to a specific dimensions
% there are many ways of interpolation to perform resizing
%resized_img3 = imresize(url_img, 0.2,'method','nearest'); % rsize by a specific interpolation method
figure, imshow(resized_img1), title('Resized image')
% change color did you mean from RGB to grayscale
gray_img = rgb2gray(resized_img1);
figure, imshow(gray_img), title ('Grayscale image')
Reinstall the image package. You somehow have a botched installation.
The function rgb2gray has always been part of the image package. It is one of the functions that has been there since the very start.
What has happened is that since version 4.4, Octave core also includes an implementation of rgb2gray. To support both old and new Octave versions, the image package checks if rgb2gray is available during installation. If so, it installs its own implementation. If not, it does nothing and defaults to the implementation in Octave core. If you have both image package and Octave 4.2 installed, and rgb2gray is not available, then you somehow messed up your installation of the image package.
Is your installation of the image package maybe done with a version of Octave different from the one you are running?
Also, consider using the octave packages that are provided by your system package manager which should not have this problem (apt install octave-image) after uninstalling the ones you installed manually.
According to Octave documentation on rgb2gray, the conversion is done as follows:
I = 0.298936*R + 0.587043*G + 0.114021*B
So converting a 3D RGB image matrix to a 2D gray-scale can be done by this code:
gray_img = (...
0.298936 * resized_img1(:,:,1) +...
0.587043 * resized_img1(:,:,2) +...
0.114021 * resized_img1(:,:,3));
When you call imread than the pixels are integers of type uint8, in this case you can round the result for better accuracy by adding 0.5:
gray_img = (...
0.298936 * resized_img1(:,:,1) +...
0.587043 * resized_img1(:,:,2) +...
0.114021 * resized_img1(:,:,3) + 0.5);
To get the pixels into a range between 0-1 use im2double
If RGB is an RGB image (a matrix of size [n,m,3]) then converting to a gray-scale image gray (an array of [n,m]) is accomplished by a weighted averaging of the 3 color channels.
Depending on your application, the best approach could be instead to take only the green channel (this is the most sensitive one, CCDs have twice as many green pixels than blue or red pixels):
gray = rgb(:,:,2);
A simple non-weighted average is often good enough:
gray = mean(rgb,3);
The Adobe D65 standard RGB uses weights of 0.2973769, 0.6273491 and 0.0752741 for red, green and blue (source). But I don’t know what weights are used by the MATLAB implementation of rgb2gray. Let’s assume it’s those weights. This code computes the weighted average:
[n,m] = size(rgb);
gray = reshape(rgb,[],3);
gray = gray * [0.30;0.63;0.07];
gray = reshape(gray,n,m);
In Octave you can write it as a one-liner:
gray = reshape(reshape(rgb,[],3) * [0.30;0.63;0.07], size(rgb)[1:2]);
If you want to write function create new function convgray.m then just paste
function[G] = convgray(F)
rgb=double(F);
[height,width,c] = size(rgb);
gray = reshape(rgb,[],3);
gray = gray * [0.30;0.63;0.07];
gray = reshape(gray,height,width);
gray=uint8(gray);
imshow(gray)
then in command window type
>> image = imread('yourimage.jpg');
>> convgray(image)
it will show your grayscale image with no error
here's my output

Split large tiff into multiple pages with correct borders

I test this on my windows machine, but in the end it should run here:
identify -version
Version: ImageMagick 6.8.9-9 Q16 x86_64 2018-09-28 http://www.imagemagick.org
I have a long tiff (1700x96274) and I split it into multiple tiff pages with this command:
magick convert large.tiff -crop 1700x2300 -page A4 cropped_%d.tiff
But then I'm cutting text or images very often. What I want is a smart border with mostly white, e.g. between 2200-2400.
How can cut the image into multiple images with detecting white (mostly) spaces and use them as variable border?

converting a ps image to gif image with length x900 y800

I have a ps image that I want to convert to a gif image with horizontal by vertical dimensions of 900 and 800 respectively. I have tried to use the command:
convert panel.gs -resize x800 y900 panel.gif
or also:
convert panel.gs -resize 900x800 panel.gif
Can you help me to tweak the convert commands so I can get the desired results?
.gs is not a valid suffix. Did you mean .ps?
Imagemagick will need ghostscript as a delegate. You did not say what was wrong nor what platform or what version of Imagemagick.
If the image does not have the same aspect ratio as the final dimensions you want, you will either 1) need to distort it to fit using !, 2) resize it and then extend to the size you want filling with background color, or 3) resize it with ^ and crop it to the size you want.
convert panel.ps -resize "900x800!" panel.gif
convert panel.ps -resize 900x800 -gravity center -background white -extent 900x800 panel.gif
convert panel.ps -resize "900x800^" -gravity center -extent 900x800 panel.gif
Well, firstly you haven't actually said what's wrong with the two commands that you have tried already.....
Your PostScript program probably does not contain an 'image' as such, PostScript is not a bitmap format its a programming language.
You can use Ghostscript to render the PostScript to an image, and then use ImageMagick to resize that image, possibly you can combine these two steps, or just perform a single conversion, it depends on what exactly you want to happen, which isn't clear.
If (for example) your PostScript program requests a media size of 9 inches by 8 then you can create a bitmap image by simply setting the resolution to 100 dpi using -r100.
If you want the image scaled differently in each direction, then you need to set a non-square resolution. For example if the PostScript program requests media of 9 inches by 4 then you need to set the resolution to 100x200 in order to get an image exactly 900 x 800 pixels. You would use -r100x200 for this.
The alternative, from a PostScript point of view, is to set the media size to a given
value in pixels (using -g900x800) and set -dDFIXEDMEDIA which prevents the PostScript program from changing it. You can then use -dFitPage which will have Ghostscript scale the content to fit the page. However it will scale the content equally in both directions, which may leave white space around the edge.
Now since Ghostscritp doesn't write GIF directly you'll need to load whatever bitmap format you select into IM in order to write it out as a GIF, so perhaps the simplest solution is just to use Ghostscript to render the PostScript to a defined resolution (eg 100 dpi) and then load that image into IM and rescale it there.
Since IM (and therefore convert) use Ghostscript to process PostScript programs, that's what's happening now so it isn't obvious to me what your problem is.

Rescaling XPM image

ALL,
I have an XPM image with the size of 10x10. What I would like to do is to scale it so that the size becomes 16x16.
Does anybody knows how I can do that?
Thank you.
With ImageMagick, which is installed on most Linux distros, and is available for macOS and Windows:
convert small.xpm -scale 16x16 bigger.xpm

How to efficiently detect bar code target in an image

I have two questions:
Firstly, how to detect the area of bar code target in an image (like the sample images), which may have a few noises.
Secondly, how to efficiently do the detection, for instance, in 1/30 seconds.
Squash (resize) the image till it is only 1 pixel tall, then normalise it to the full range of 0-255 and threshold. I am using ImageMagick at the command-line here - it is installed on most Linux distros and is available for OSX and Windows also with Python, PHP, Ruby, C/C++ bindings.
convert barcode.png -resize x1! -scale x10! -normalize -threshold 50% result.png
I have then scaled it to 10 pixels tall so you can actually see it on here - but you would keep the original width and have a height of one pixel. Then just find the first white pixel in your single row of pixels.
Your recently added, smaller barcode gives this:

Resources