How to group pixels in an image? - image-processing

I want to group 16 pixels into a single unit in an image.
For eg: If the image is a 16 x 16 image then the number of cells(ie, group of 16 pixels=1cell) that I would be creating will be 16. How to create a cell and display each cell with the respective pixel values?

I am not 100% sure I understand the maths of your question, but let's assume you have this image which is 48x32 - I am showing the images 10x larger than life so you can see them.
I would use ImageMagick, which is installed on most Linux distros, and is readily downloadable for OS X and Windows. Download here or use homebrew on OS X.
I presume you want to chop the image up into lumps that measure 16x16, so you would use this command:
convert -crop 16x16 +repage tile%d.png
and you will get 6 output files, one red, one green, one blue, one black one white and one grey, called tile0.png, tile1.png ... tile5.png.
tile0.png
tile1.png

Related

ImageMagick convert from pdf to image shrinks image and places it in bottom left corner

I am using this command to convert pages from a pdf to jpeg images:
magick convert -density 300 sample.pdf output.jpeg
I see a white background and the content of the PDF appears as a smaller image stuck to the bottom left corner of the white "canvas". Can anyone help with why this might be happening and how to prevent this "shrinking"?
My PDF has 14 pages. Here is the metadata for a few of those pages:
>magick identify sample.pdf
sample.pdf[0] PDF 2286x3600 2286x3600+0+0 16-bit sRGB 6458B 0.016u 0:00.017
sample.pdf[1] PDF 2286x3600 2286x3600+0+0 16-bit sRGB 6018B 0.016u 0:00.020
sample.pdf[2] PDF 2286x3600 2286x3600+0+0 16-bit sRGB 5732B 0.016u 0:00.023
And here are the actual and expected outputs for one of the pages:
actual output:
expected output:
edit: here is a sample PDF:
https://www.dropbox.com/s/0bzu5brfzbedd7i/sample.pdf?dl=0
I am not sure why you have that behavior. There is something in the PDF, perhaps a crop box, that Imagemagick/Ghostscript is not picking up. But you can get rid of the excess white using -trim
magick sample.pdf -trim sample_%d.jpg
Thanks for the example
> magick identify sample.pdf
> sample.pdf[0] PDF 2286x3600
Apears to be wrong as there is no match
from the PDF contents
/Width 1531
/Im0
/Height 2454
/MediaBox [0 0 1531 2454]
on
Page Size:
/CropBox [0 0 919 1473]
919 pt x 1473 pt
32.42 x 51.96 cm
12.76 x 20.45 inches
Therefore no problems when the images were inserted as # 120 dpi
We can check the image by copy when zoom to 100% in a viewer and paste into say paint, which agrees the image is 1531 x 2454 pixels.
As a result of comments with #fmw42, it was decided to see if GhostScript (which ImageMagick depends on for PDF handling) was having an affect, and certainly processing that PDF using GS v 9.55 without any special switches gave warnings and produced the output below left So the issue seems to be caused by recent GhostScript method of calling/scaling. since using simple GhostScript based image apps (Irfanview using GS plugin on the left) behave the same whilst other viewers have less of a problem even sister product MuPDF as previewed on the right. So the file Media Box as seen and probably used for scaling by Ghostscript seems to be the culprit, but was processed by two other PDF handlers during generation.
One solution would be to use a simpler method of extracting images as PNG thus look at Xpdf command line tools "pdftopng" which gives a good result but you need to calculate that the optimum resolution in this case is 120 (or 240), Typical windows command line does not need .exe but its best to use that when prefixing with a path for use from another location.
pdftopng.exe -r 120 -f 1 -l 1 sample.pdf

Overlaying multiple PNG images of different sizes on a canvas using ImageMagick

I want to overlay multiple PNG images of different sizes on a transparent canvas using ImageMagick. First I create a transparent canvas of some fixed size, say like
convert -size 1500x1000 canvas:transparent PNG32:canvas.png
Then I loop over my images in order to add each image to the canvas
convert canvas.png nthimage.png -gravity Center -geometry xResxYres+xcoord+ycoord -composite canvas.png
This works fine, but I may overlay as many as 10 pictures and I do this for thousands of n-tuples of images, so a faster solution would be appreciated. So my question: Can I also do this in one step instead of creating the canvas first and then adding a single image at a time?
Edit: I use ImageMagick 7.0.11-13 on macOS 10.15.7. I run ImageMagick from within a python script, so a file containing a list of input files can be generated if needed. For concreteness, say my input files are file_1.png up to file_n.png with sizes A1xB1 up to AnxBn and should be placed at coordinates +X1+Y1 up to +Xn+Yn with respect to the center of the canvas and the output file is output.png and should have size 1500x1000.
I really wouldn't recommend shelling out subprocesses from Python to call ImageMagick thousands of times. You'll just end up including too much process creation overhead per image, which is pointless if you are already running Python which can do the image processing "in house".
I would suggest you use PIL, or OpenCV directly from Python, and as your Mac is certainly multi-core, I would suggest you use multi-processing too since the task of doing thousands of images is trivially parallelisable.
As you haven't really given any indication of what your tuples actually look like, nor how to determine the output filename, I can only point you to methods 7 & 8 in this answer.
Your processing function for each image will want to create a new transparent image then open and paste other images with:
from PIL import Image
canvas = Image.new('RGBA', SOMETHING)
for overlay in overlays:
im = Image.open(overlay)
canvas.paste(im, (SOMEWHERE))
canvas.save(something)
Documentation here.

How to remove antialias edge in ImageMagick when converting to a binary bitmap?

We're doing a cognitive experiment that requires flashing 480 black-and-white images at high speed against a neutral-gray background. The image shown is detail at about 300% zoom; the full display is 932 x 612; there are actually other clusters similar to this one elsewhere on the screen.
We have to generate these images in a source app and later display them in the experimental app. At first, we were using 24-bit PNG's with the background color built in, but despite the size of each file hovering around 10KB, the total file payload of 480 is too large and takes way too long to preload. We can, however, set a default background color in the app and put up 1-bit images. Although we can change the background color in the source application, we don't have control over bit depth there, so we are stuck generating screen captures and then downsampling to binary. We have tried this with original images that sit on both a white background and the gray background. Using ImageMagick, both of these commands yield similar results:
magick gray.png -transparent "rgb(192,192,192)" -alpha set -depth 1 out\gray-out.bmp (or .png)
magick white.png -transparent white -alpha set -depth 1 out\white-out.bmp (or .png)
The PNGs are coming out to 1.5K to 5K, so this is where we want to be. However, we're stuck with that problem aliased edge whether we start with gray- or white-background images. We've also tried the -fuzz argument (1-99%) to no effect. The resulting pseudoalias artifact that we see in these 1-bit files is the same in multiple apps, so apparently it must be built into the output file generated by ImageMagick's attempt to filter the edge, and not an artifact of any single app or the OS.
We don't quite get how an alpha channel can even be attached to a 1-bit image if it is not strictly RGBA: an alpha channel with a 1-bit image doesn't even make sense. But if an alpha channel isn't being included, then where is the map coming from in a nonbinary image to distinguish that "white" edge from a nonwhite surface? It's not the destination apps. The output files must either not be strictly binary, or else ImageMagick is not computing the channel exactly to the contour edges. (When we remove the -alpha argument, ImageMagick generates a larger file; the aliasing (e.g., when we place into PowerPoint and select Transparent Color to white) may appear in slightly different places, but the effect is essentially the same.
The question is, how is it possible to remove this artifact in a 1-bit image using ImageMagick? We'd like to get the file sizes down to the minimum.

Xcode 9 renders P3 PDF assets into SRGB

I've spent hours in trying to figure this one out.
Goal
Display P3 PDF Asset in UIImageView (the PDF is 100% in P3 Color Space).
Issue
I'm creating a P3 PDF asset and adding into the Xcode. Within the Asset Catalog, the asset appears in the correct P3 color. When using the asset inside UIImageView and running on iPhone X ( physical device, supports P3 Color Space ), the asset showing is SRGB instead of P3.
Does anyone has information on how to resolve this issue?
Any help will be highly appreciated.
Roi
Use PNG directly
You mention you suspect there is a PNG inside the PDF. I would recommend to use PNG directly without a wrapping PDF.
PDFs are rendered by Apple to PNG when they are deployed on a device. This rendering may apply a specific color profile (PDF and color management is a broad topic).
Also the rendering itself might not produce the results you are expecting, see e.g. https://bjango.com/articles/idontusepdfs/
16 bits per pixel (per channel)
Apple's Human Interface Guidelines state one has to use 16 bits per pixel and export images in .png format.
When appropriate, use the Display P3 color profile at 16 bits per pixel (per channel) and export images in .png format.
see here: https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/color/#color-management
Finally, I'd like to mention just two more settings that you are probably already using:
Compression
In the attributes inspector for image assets you should choose 'Lossless'.
Gamut
Swicht Gamut to 'sRGB and Display P3' and then make sure your image is in a 'Display P3' slot in the .xcasset file.
Test with PNG export of Sketch
Taking a look at the chromaticity diagram, one can see that the P3 color space has a larger gamut for greenish colors.
Since I am not sure whether I can recognize the difference between the two color spaces, I have made the following experiment:
inserted a artboard in Sketch
created a green rectangle with the color #00FF00
assigned under <File/Change Color Profile> the Display P3 color profile
selected the rectangle and clicked Exported selected
have chosen .png without interlacing
Then I did the very same but with sRGB ICE61966-2.1 profile.
I checked both .pngs in the ColorSync utility (can be found under /Applications/Utilities). Pressing the image info toolbar button one can see, that the correct ColorSync profiles are assigned.
In Affinity Photo I checked under <Document/Colour Format> the number of bits per channel. It was for both .pngs 8bit per channel, so I created two additional .pngs with 16bits per channel and named it accordingly.
Then I added the 4 .pngs to a .xcassets folder with the following settings:
Compression: 'Lossless'
Scale: 'Single Scale'
Gamut: 'sRGB and Display P3'
assigned the .pngs accordingly to the correct slot (either sRGP or Display P3).
Then I deployed to iPhone X.
Result: Actually I can see a difference between the green rectangles. The 'Display P3' do have indeed a more saturated green.
I exported the same thing to an old iPhone, where I can't spot any differences between the sRGB and Display P3 images.
I found it interesting that the 8-bit variant directly from Sketch also works, so 16 bits per channel doesn't seem to be a hard requirement.
Did you select the gamut setting for your asset?
How did you verifiy that the image is in SRGB on the iPhone X?
Maybe the WWDC16 talk is somethink to check again:
talk slides

How can I convert image background pattern?

On this similar thread they have been proposed solutions to convert the background color of some image to transparent.
But sometimes the background is a simple pattern, like in this case:
Note the square background pattern.
When processing images, the background does often need to be removed or changed, but firstly you need to detect it (i.e: change its color, or making it transparent). For example, on the above image example, I would like to obtain:
How can I detect/change a specified pattern inside an image?
GUI solutions accepted.
Open source solutions preferred (free at least required).
The simplest solution will be preferred (I would like to avoid installing some hundreds of MB program).
Note: I was thinking about posting this question at Photography
StackExchange site, but I would rather say the mind of a programmer (I
could need to edit dozens of such images) is more close to what I
want. I am not an artist.
This is not a fully developed answer, but it does go some way towards thinking about a method - maybe someone else would like to develop it...
If, as you say, your pattern is specified, you know what it is - good, aren't I? So, you could look for the "Minimum Repeating Unit" of your pattern in your image. In your case it is a 16x16 grid like this:
Now you can search for that pattern in your image. I am using ImageMagick at the command-line, but you can use other tools if you prefer. ImageMagick is installed on most Linux distros and is available for OSX and Windows for free. So, I search for that grid in your globe image and ImageMagick gives me an output image showing white dots at the top-left corner of every location where the two images match:
compare -metric ae -dissimilarity-threshold 1.0 -compose src -subimage-search globe.gif grid.png res.png
That gets me this in file res-1.png
Now the white dots are where the 16x16 "Minimum Repeating Unit" is found in the image, but at the top-left corner so I shift them right and down by 8 pixels to the centre of the matching area, then I create a new output image where each pixel is the maximum pixel of the 16x16 grid in which it existed before:
convert res-1.png -roll +8+8 -statistic maximum 16x16 z.png
I can now invert that mask and then use it to set the opacity of the original image, thereby blanking areas that matched the "Minimum Repeating Unit":
convert globe.gif \( z.png -negate \) -compose copy_opacity -composite q.png
No, it's not perfect, but it is an idea for an approach that could be refined...

Resources