PIL Image, cut from one image to another - python

I'm trying to cut a section from one image and paste it into another. I'm using the following code:
img1 = Image.open("Img1.png")
img2 = Image.open("Img2.png")
cut = img2.crop((31, 0, 47, 15))
cut.save("cut.png")
img1.paste(cut, (150,300))
img1.save("NewImg1.png")
When I look at cut.png I see the right part cut out. However when it's pasted into img1, the resulting image just has a black box where the pasted section should be.
I suspect this may more be an issue with my images than the code, (both were created in Paint.NET, saved with default options) but I don't really know where to look right now to figure out the problem.

Related

Why can't tesseract extract text that has a black background?

I have attached a very simple text image that I want text from. It is white with a black background. To the naked eye it seems absolutely legible but apparently to tesseract it is a rubbish. I have tried changing the oem and psm parameters but nothing seems to work. Please note that this works for other images but for this one.
Please try running it on your machine and see if it works. Or else I might have to change my ocr engine altogether.
Note: It was working earlier until I tried to add black pixels around the image to help the extraction process. Also I don't think that tesseract was trained on black text on a white background. It should be able to do this too. Also if this was true why does it work for other text images that have the same format as this one
Edit: Miraculously I tried running the script again and this time it was able to extract Chand properly but failed in the below mentioned case. Also please look at the parameters I have used. I have read the documentation and I feel this would be the right choice. I have added the image for your reference. It is not about just this image. Why is tesseract failing for such simple use cases?
To find the desired result, you need to know the followings:
Page-segmentation-modes
Suggested Image processing methods
The input images are boldly written, we need to shrink the bold font and then assume the output as a single uniform block of text.
To shrink the images we could use erosion
Result will be:
Erode
Result
CHAND
BAKLIWAL
Code:
# Load the library
import cv2
import pytesseract
# Initialize the list
img_lst = ["lKpdZ.png", "ZbDao.png"]
# For each image name in the list
for name in img_lst:
# Load the image
img = cv2.imread(name)
# Convert to gry-scale
gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Erode the image
erd = cv2.erode(gry, None, iterations=2)
# OCR with assuming the image as a single uniform block of text
txt = pytesseract.image_to_string(erd, config="--psm 6")
print(txt)

Adding black borders to image without quality loss

I have a 21:9 image with 1920x816 resolution, and i want to add black bars on top and bottom in order to comapre it with same one with 1920x1080 resolution . I tried 2 solutions for that, one using OpenCV and second using Image from Pillow. However, both of those reduced quality of images.
Not edited images are taken from video file using VapourSynth and FFMS2.
Comparison between files: (1920x816 frame.png and 1920x1080 frame.png are not edited files)
https://diff.pics/rKVbxTRRPG35
Am i missing some important options that will prevent quality loss? Or should i use different library for that?
Code that i used for OpenCV:
import cv2
img = cv2.imread('1920x816 frame.png')
color = [0, 0, 0]
top, bottom, left, right = [132, 132, 0, 0]
img_with_border = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)
cv2.imwrite("1920x1080 after OpenCV.png", img_with_border)
And for Pillow:
from PIL import Image, ImageOps
old_im = Image.open("1920x816 frame.png")
new_im = ImageOps.expand(old_im, border=(0, 132))
new_im.save("1920x1080 after Pillow.png", "PNG")
Doesn't look like there's a difference i quality. But there is a difference in Gamma value between the image files. Your original was saved with gamma 0.45455, and the processed image was saved with no gamma value.
Here's an explanation of what gamma means in png files: https://hsivonen.fi/png-gamma/
It's probably best to just strip the gamma value from both images. Pillow doesn't provide any simple way to work with the gamma metadata, and I'm not sure if openCV does either.
After some searching, i realized that i am an idiot. If i take frame with Vapoursynth, i might as well use it to add the needed border.
video = core.std.AddBorders(clip = video, top = 132, bottom = 132, color = [0,0,0])
That gets the job done without any additional compression. Maybe someone will make use of it.

OpenCV cv2.rectangle output binary image

I have been trying to draw rectangle on a black image, uscv2.rectangle.Here is my code : (It is just a sample, in actual code there is a loop i.e values x2,y2,w2,h2 changes in a loop)
heir = np.zeros((np.shape(image1)[0],np.shape(image1)[1]),np.uint8);
cv2.rectangle(heir,(x2,y2),(x2+w2,y2+h2),(255,255,0),5)
cv2.imshow("img",heir);
cv2.waitKey()
It is giving the following output:
Why the image is like that? Why the boundaries are not just a line a width 5.
I have tried, but I am not able to figure it out.
Can't post this in a comment, but it's a negative answer: the same operations work for me on Windows/python 2.7.8/opencv3.1
import numpy as np
import cv2
heir = np.zeros((100,200),np.uint8);
x2=10
y2=20
w2=30
h2=40
cv2.rectangle(heir,(x2,y2),(x2+w2,y2+h2),(255,255,0),5)
cv2.imshow("img",heir);
cv2.waitKey()
Because you are loading the image to be tagged (draw rectangles) in grayscale, thats why when you are adding rectangles/bounding boxes the colors are being converted to grayscale.
To fix the issue, open image in "color" format. Since, you didn't included that part of code, here is the proposed solution:
tag_img = cv2.imread(MYIMAGE,1)
Pay attention to the second parameter here, which is "1" and means load image as color. Read more about reading images here: https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_gui/py_image_display/py_image_display.html

How to merge 2 transparent png's in python Pillow

I have 2 transparent PNG images of the same size (142,43). I am trying to vertically stack them. This is one of them:
The end result should be like this (142,86):
It also should retain its transparancy.
I've tried the following code:
from PIL import Image
img_list = [Image.open("example.png"), Image.open("example.png")]
bg = Image.open("1x1_transparent.png")
bg = bg.resize(size=(142, 43*2))
img_list[0] = img_list[0].convert('RGBA')
bg.paste(img_list[0], (0, 0), img_list[0])
bg.save('final.png')
Which imports a 1x1 transparent image, resizes it to the final target size, then tries to put the first image on it. This does not work. The saved image 'final.png' shows an empty image.
Any thoughts what I would be doing wrong?
If your output doesn't seem properly sized, it's probably because of this line:
bg.resize(size=(142, 43*2))
resize returns a new version of the image, leaving the original one unmodified. Try assigning the returned value to something so you can do additional operations on it and ultimately save the output.
bg = bg.resize(size=(142, 43*2))

Transparent PNG in PIL turns out not to be transparent

I have been hitting my head against the wall for a while with this, so maybe someone out there can help.
I'm using PIL to open a PNG with transparent background and some random black scribbles, and trying to put it on top of another PNG (with no transparency), then save it to a third file.
It comes out all black at the end, which is irritating, because I didn't tell it to be black.
I've tested this with multiple proposed fixes from other posts. The image opens in RGBA format, and it's still messed up.
Also, this program is supposed to deal with all sorts of file formats, which is why I'm using PIL. Ironic that the first format I tried is all screwy.
Any help would be appreciated. Here's the code:
from PIL import Image
img = Image.open(basefile)
layer = Image.open(layerfile) # this file is the transparent one
print layer.mode # RGBA
img.paste(layer, (xoff, yoff)) # xoff and yoff are 0 in my tests
img.save(outfile)
I think what you want to use is the paste mask argument.
see the docs, (scroll down to paste)
from PIL import Image
img = Image.open(basefile)
layer = Image.open(layerfile) # this file is the transparent one
print layer.mode # RGBA
img.paste(layer, (xoff, yoff), mask=layer)
# the transparancy layer will be used as the mask
img.save(outfile)

Categories

Resources