Removing highlighted areas when converting pdf to image? - python

I'm trying to convert pdfs to png which usually works great but I occasionally get this result.
There's two parts that are 'highlighted' which I'm not sure why since ImageMagick doesn't consistently do this.
Here's the code I'm working with:
with Image(filename=pdf, resolution=200) as src:
src.background_color = Color('white')
src.alpha_channel = 'remove'
images = src.sequence
Image(images[1]).save(filename='test.png')
I thought maybe there was a problem with transparency so the first two lines are related to this question.
How can I get this image to just show up normally like this
image which looks correct? Thanks!

The issue you have is that your input has an alpha channel. So just removing the alpha channel or flattening it on white leaves that area as gray, since it is in the underlying image.
The best way to fix that is using ImageMagick -lat function.
See http://www.imagemagick.org/script/command-line-options.php#lat
As I do not have your original, I can only process your resulting PNG file, which shows this behavior.
Input with transparency
Processing
convert input.png -background white -flatten -negate -lat 25x25+10% -negate result.png

Related

tv-like noise b/w background removal from .jpg image

I'd like to remove this sort of tv-like noise from a .jpg image in order to get a .png image with transparent background.
This is because I'll later need to overlay this picture over another one.
I've tried 1,
2,3, but all of them probably work only on black backgrounds.
I'm coding with Python and I thought OpenCV would help.
Do you have any idea? Thanks! :)
Given that the noise is nearly exclusively black and white (i.e. desaturated) whereas the fish is colour, I would convert to HSV colourspace and look to the Saturation channel for providing separation - the middle one in the row below:

How to repair obscured blocks in a QR code image

I have many RGB images that contain a printed sheet of paper with a QR code in an outdoor setting. Because of the bright sun interfering with image capture, about 20% of images are unreadable:
I'm using magick in R to handle the image manipulation, and then the Python package pyzbar (which wraps zbar) to do the detection.
I can use image_threshold to find all the pixels that are within the 95% quantile and force them to pure black, which fixes about half my images:
But some of them remain unreadable, like this one. I can see with my human eyes that I need to fill in some of the anchor points in the upper left, so I mocked this up in MS Paint:
With that manual manipulation, this image is now easily read. Is there any way to do this kind of repair automatically? I don't mind translating code from Python or the ImageMagick CLI, so R-only answers aren't necessary.
My general approach:
library(magick)
library(reticulate)
pyzbar <- import("pyzbar.pyzbar")
magick_to_numpy <- function(img) {
round(255 * as.numeric(magick::image_data(img, "rgb")))
}
image_read("testfile.jpg") %>%
image_threshold("black", "95%") %>%
magick_to_numpy() %>%
pyzbar$decode()
Usual result:
list()
Desired result:
[[1]]
Decoded(data=b'W TRR C6 T2', type='QRCODE',
rect=Rect(left=176, top=221, width=373, height=333),
polygon=[Point(x=176, y=226), Point(x=202, y=554),
Point(x=549, y=544), Point(x=524, y=221)])
You may be able to improve some of your images, but the one you provided has lost too much black to pure white. So gaps will appear that are too large to close up. The best way I know in Imagemagick command line, would be to process the image converted to grayscale using -lat (local area thresholding) and perhaps some morphology open.
Input:
convert img.jpg -colorspace gray -negate -lat 50x50-1% -negate -morphology open square:7 result.png
Normally one would use the % term as positive. But here you have lost too much data and I want to include as much as possible that is not pure white before it makes too much black. So I push it to -1%. The -negate is needed since -lat works only on white objects on black background. So I have to negate before and after. I then try to fill some the black regions using some morphology open.

How to pad images to a specific size like 720*576 with a pixel value/border value?

I have images of various sizes like 122*98, 98*65, 320*256, 620*540. How to make all images to a fixed size say 720*576 by padding them with border/some pixel value? Is there a generic way to do it which works for input images of any size? I tried some methods using PIL module, but didn't get a generic solution.
I am assuming you are pretty tool-agnostic since you have tagged with OpenCV, PIL/Pillow and skimage, so I would suggest just using ImageMagick on the command line:
So, starting with these images as 1.png, 2.png and 3.png:
You can make an output directory and put them all in the North-West corner of a magenta background:
mkdir output
magick mogrify -path output -background magenta -extent 720x576 [123].png
Or, put them all in the centre of a yellow background:
magick mogrify -path output -gravity center -background yellow -extent 720x576 [123].png
Omit the -path output if you want the files overwritten in place.
Omit the word magick if running v6 or older.
If you specifically want to do it in Python, one way is to make a solid canvas of the correct size and padding colour that you want as an output image and then paste your image onto that canvas, either at top-left or centred using some simple maths.
Another option is PIL/Pillow's ImageOps.expand() like here.
You're looking for the cv2.remap() function. This function has a parameter that let's you define a constant border value. The Opencv tutorial at https://docs.opencv.org/3.4/d1/da0/tutorial_remap.html should give you enough info to start. The if-block ind == 0: in the tutorial resizes the image by 50%. You should be able to use this to get the fixed size of 720x576.

python: when reading and saving a image the color change

I tried loading and saving images with python using cv2,PIL, scipy , but the saved image has a bit different color compare to the original.
I am loading and saving tif format, so i expect no color change.
link to the image I am using:
https://data.csail.mit.edu/graphics/fivek/img/tiff16_c/a0486-jmac_MG_0791.tif
the difference between loaded image and saved image is:
can you help me understand what I am doing wrong? why the color change?
update:
the problem is because the image is prophoto rgb color.
does anyone knows how can i convert a batch of images from prophoto rgb to rgb?
thanks,
yoav
option 1:
img = imread(file_name)
imsave('imread.tif', img)
option 2:
img = cv2.imread(file_name)
cv2.imwrite('cv2.tif', img)
option 3:
img = Image.open(file_name)
img.save('pil.tif')
I think OpenCV is more interested in Computer Vision - i.e. detecting and measuring objects etc than printing or high quality image reproduction, editing and printing, so it pretty much ignores ICC profiles. If anyone knows better, I am happy to be corrected.
You can use ImageMagick to convert images from one format to another, and to do many, many other things, one of which is changing colour profiles. So, I think, if you go to this website and download an sRGB profile (I chose the first one with "preference" in its name) and save it as sRGB.icc, you can change one of your ProPhoto images to a normal sRGB image with the following command in Terminal:
convert input.tif -profile sRGB.icc output.tiff
Try that and see if it works. If so, make a copy of your images and on a copy, you can run mogrify to do the whole lot in one go - beware and make a copy like I suggest because it will very quickly alter all your images...
magick mogrify -profile sRGB.icc *tif
You can see the embedded profile and loads of other information about an image using ImageMagick's identify command:
magick identify -verbose OneOfYourImages.tiff

PIL paste image without blur

I want to paste an image into a single coloured background using PIL but some blures and noises appear around pasted photo like this:
(Zoom photo to see noises. I think it is due from Antialiasing) But I want to paste with sharp boundaries like here :
I am using this codes for paste:
my_image.convert('RGBA')
background = Image.new("RGBA", (background_size), background_color)
background.paste( my_image, (coordinates), my_image )
background.save("result.jpg")
What sholud i do for pasting with sharp boundaries?
Thanks.
jpg is a lossy format, so it may blur your image or add noise, in order to save memory. Use a lossless format like png instead:
background.save("result.png")

Categories

Resources