I recently started to learn how to work with Pillow in python and this is what i have so far (code below).
If i run this i get the following error:
ValueError: cannot determine region size; use 4-item box
i've tried removing the base.paste line, this removes the error but doesn't show any text.
i hope someone here could help me to fix this so the text is showing in the image.
#app.route("/imgtest/")
def imgtest():
f_text = textwrap.fill(request.args.get('text'), 10)
base = Image.open(config.assetsfolder+'/'+'facts.bmp').convert("RGBA")
txtO = Image.new("RGBA", base.size, (255, 255, 255, 0))
font = ImageFont.truetype(config.assetsfolder+'/'+'fonts'+'/'+'Roboto-Bold.ttf', 15)
canv = ImageDraw.Draw(txtO)
canv.text((95, 283), f_text, font=font, fill="Black")
base.paste(f_text)
base.save(config.assetsfolder+'/'+'done'+'/'+'boop.png')
return send_file(config.assetsfolder+'/'+'done'+'/'+'boop.png')```
How do i show the text in the image?
If you are using pillow 4.0, I believe this would be an issue with the pillow version. Try in your cmd the following:
pip uninstall pillow
pip install Pillow==3.4.2
Played a bit around by adding some random code and reading the docs a bit better
#app.route("/fact/")
def fact():
filename=(config.assetsfolder+'/'+'facts.bmp')
args=request.args.get('text')
font = ImageFont.truetype(config.assetsfolder+'/'+'fonts'+'/'+'Roboto-Bold.ttf', size=20)
text = wrap(font, args, 340)
im = Image.open(filename)
text_layer = Image.new('RGBA', im.size)
d = ImageDraw.Draw(text_layer)
location = (90, 600)
text_color = (20, 20, 20)
d.text(location, text, font=font, fill=text_color)
text_layer = text_layer.rotate(-13, resample=Image.BICUBIC)
im.paste(text_layer, (0, 0), text_layer)
im.save(config.assetsfolder+'/'+'done'+'/'+'fact.png')
return send_file(config.assetsfolder+'/'+'done'+'/'+'fact.png')
This did the job for me.
Related
I am trying to make a project which has three imshow windows each of different size, is there a way to make those three windows to pane or stack and display them in another window? Currently they are displayed like this
How can i make a window which will contain all these windows and only the main window will have a close button and not all of them.
Use
To stack them vertically:
img = np.concatenate((img1, img2), axis=0)
To stack them horizontally:
img = np.concatenate((img1, img2), axis=1)
Then show them using cv2.imshow
You can read in each image and store all but the first one, img0, into a list, imgs. Iterate through each image in the imgs list, comparing the width of img0 and the image of the iteration. With that we can define a pad, and update the img0 with the image:
Lets say we have these three images:
one.png:
two.png:
three.png:
The code:
import cv2
import numpy as np
img1 = cv2.imread("one.png")
img2 = cv2.imread("two.png")
img3 = cv2.imread("three.png")
imgs = [img1, img2, img3]
result = imgs[0]
for img in imgs[1:]:
w = img.shape[1] - result.shape[1]
pad = [(0, 0), (0, abs(w)), (0, 0)]
if w > 0:
result = np.r_[np.pad(result, pad), img]
else:
result = np.r_[result, np.pad(img, pad)]
cv2.imshow("Image", result)
cv2.waitKey(0)
Output:
I'm having a quite big issue with fitellipse and opencv-python.
I know that I have to install opencv-contrib-python to get some functions but it doesn't work with fitellips function.
when using :
import cv2
cv2.fitEllipse()
here is the result:
TypeError: fitEllipse() missing required argument 'points' (pos 1)
but if now I try it using, for example, contour detection from an image:
img = cv2.imread('messi5.jpg',0)
retz,bawgray=cv2.threshold(img , 110,255,cv2.THRESH_BINARY)
contours,hierarchy = cv2.findContours(bawgray,1,1)
cnt = contours
big_contour = []
maxop = 0
for i in cnt:
areas = cv2.contourArea(i)
if areas > maxop:
maxop = areas
big_contour = i
img=cv2.drawContours(img, big_contour, -1, (0,255,0), 3)
cv2.FitEllipse(big_contour)
here is the result:
AttributeError: module 'cv2.cv2' has no attribute 'FitEllipse'
I use opencv-python 4.2.0.34
and opencv-contrib-python 4.2.0.34
You have not provided output for cv2.fitEllipse. Also you have misspelled the name. It is "fitEllipse" not "FitEllipse" with lower case "f".
Try
result = img.copy()
((centx,centy), (width,height), angle) = cv2.fitEllipse(big_contour)
cv2.ellipse(result, (int(centx),int(centy)), (int(width2/),int(height2/)), angle, 0, 360, (0,0,255), 1)
The used font: https://www.fontspace.com/abeezee-font-f30774
ImageFont.truetype(*path/to/font*, 300)
font.getsize("1\n\r0\n\r9") # returns: (1080, 280) which is wrong!
image = np.full(shape=(1, 1, 3), fill_value=0, dtype=np.uint8)
image = Image.fromarray(image, mode="RGB")
draw = ImageDraw.Draw(image)
draw.multiline_textsize(text="1\n\r0\n\r9", font=font, spacing=0) # returns: (180, 837) which is correct"
Why are the results different? What am I missing?
So The main error was:
1) for multiline text we should use:
PIL.ImageDraw.ImageDraw.multiline_text(xy, text, fill=None, font=None, anchor=None, spacing=0, align="left", direction=None, features=None, language=None)
In addition .getsize() returned a height that is a little too big. The height that worked for me was:
font.getmask(digit).size[1]
wich is the same to:
font.getsize(digit)[1] - font.getoffset(digit)[1]
I am trying to detect logo in invoices. Though I am able to get some results but not sufficient enough to process. While detecting logos, Unwanted text is also getting detected.
The following is from actual invoice:-original Image
and the following results I am getting Image after operations
I am using the`following code which I have written:-
gray=cv2.imread("Image",0)
ret,thresh1 = cv2.threshold(gray,180,255,cv2.THRESH_BINARY)
kernel_logo = np.ones((10,10),np.uint8)
closing_logo = cv2.morphologyEx(thresh1,cv2.MORPH_CLOSE,kernel_logo,
iterations = 1)
n=3
noise_removed_logo = cv2.medianBlur(closing_logo, n)
eroded_logo = cv2.erode(noise_removed_logo,kernel_logo, iterations = 8)
dilated_logo=cv2.dilate(eroded_logo,kernel_logo, iterations=3)
Could you please help me what changes should I make to remove noise from my documented image. I am new to Computer Vision
Few more sample:- Original document
The result I am getting:- Result after operations on document
Hello Mohd Anas Khan .
Your approch to define logo is too simple so it couldn't work. If you want a product-level approach, use some machine learning or deep learning. If you want just some toys, then a simple countours finder with fixed rules should work.
For example, in the following approach i defined "logo" as "the contour which has biggest area". You'll need more rules later, so good luck.
import numpy as np
import cv2
im = cv2.imread('contours_1.jpg')
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,127,255, cv2.THRESH_BINARY_INV)
rect_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
threshed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, rect_kernel)
cv2.imwrite("contours_1_thres.jpg", threshed)
im2, contours, hierarchy = cv2.findContours(threshed,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
ws = []
hs = []
areas = []
for contour in contours:
area = cv2.contourArea(contour)
x, y, w, h = cv2.boundingRect(contour)
print("w: {}, h: {}, area: {}".format(w, h, area))
ws.append(w)
hs.append(h)
areas.append(area)
max_idx = np.argmax(areas)
cv2.drawContours(im, [contours[max_idx]], -1, (0, 255, 0), 3)
# cv2.drawContours(im, contours, -1, (0, 255, 0), 3)
cv2.imwrite("contours_1_test.jpg", im)
The output images are as follow : (The detected logo is covered in green box )
I am trying to do some image processing in Python using PIL. I need to raise a flag is the picture is has red colour in it. Can someone please give me some pointers?
I figured one can use split function on an image and split it into the individual channels. After this, I am not sure what to do.
Try something like this. It iterates over each pixel and checks if it's the one you want.
from PIL import Image
desired_colour = (255, 0, 0)
im = Image.open("myfile.jpg")
w, h = im.size
pix = im.load()
found = False
for i in range(w):
for j in range(h):
if pix[i, j] == desired_colour:
# Bingo! Found it!
found = True
break