How to add a text in the captured image - python

I have created a app which capture the image and convert into pencil sketch.
I need to add a watermark inside the capture image I find for the documentation I didn't get the exact one let me know how to add a water mark inside the image or any idea would be appreciated.
import base64
import streamlit as st
import numpy as np
from PIL import Image
import cv2
def dodgeV2(x, y):
return cv2.divide(x, 255 - y, scale=256)
def pencilsketch(inp_img):
img_gray = cv2.cvtColor(inp_img, cv2.COLOR_BGR2GRAY)
img_invert = cv2.bitwise_not(img_gray)
img_smoothing = cv2.GaussianBlur(img_invert, (21, 21),sigmaX=0, sigmaY=0)
final_img = dodgeV2(img_gray, img_smoothing)
logo_img = cv2.imread("Watertext.jpg")
logo_gray = cv2.cvtColor(logo_img, cv2.COLOR_BGR2GRAY)
logo_height, logo_width = logo_gray.shape[:2]
#y_offset = x_offset = 0 # paste to the top left of image
x_offset = final_img.shape[1] - logo_width
y_offset = 0
final_img[x_offset:x_offset+logo_height, y_offset:y_offset+logo_width] = logo_gray
return(final_img)

Modify your pencilsketch function like
def pencilsketch(inp_img):
img_gray = cv2.cvtColor(inp_img, cv2.COLOR_BGR2GRAY)
img_invert = cv2.bitwise_not(img_gray)
img_smoothing = cv2.GaussianBlur(img_invert, (21, 21),sigmaX=0, sigmaY=0)
final_img = dodgeV2(img_gray, img_smoothing)
logo_img = cv2.imread("path/to/logo/image.jpg")
logo_gray = cv2.cvtColor(logo_img, cv2.COLOR_BGR2GRAY)
logo_height, logo_width = logo_gray.shape[:2]
x_offset = y_offset = 0 # paste to the top left of image
final_img[y_offset:y_offset+logo_height, x_offset:x_offset+logo_width] = logo_gray
return(final_img)
If you want to paste in top right, change line
x_offset = y_offset = 0 # paste to the top left of image
to
x_offset = final_img.shape[1] - logo_width
y_offset = 0
If you want to paste in bottom right, change line
x_offset = y_offset = 0 # paste to the top left of image
to
x_offset = final_img.shape[1] - logo_width
y_offset = final_img.shape[0] - logo_height

Make use of cv2.addWeighted() which is used to blend images.
This is an example:
output_img = cv2.addWeighted(input_img, 1, watermark, 0.5, 0)

using OpenCV you can add a watermark on your photos and video also, you need to import the library and use it.
**import cv2
img = cv2.imread('diego-jimenez-A-NVHPka9Rk-unsplash.JPG')
watermark = cv2.imread("Watermark.JPG")**
for more references go to this blog post

Related

OpenCV wont object detect with MSS screen capture

I'm new to Python and want to learn it bit by bit, so I decided to write a simple program that would, in real time, capture my screen and do object detection. Through a lot of googling and reading, I was able to make this script, however, no matter what I do, it won't do object detection (m1.png).
Can you please assist me with the reason why it is like this?
import time
import cv2
import mss
import numpy
#template and dimensions
template = cv2.imread("m2.png")
template_gray = cv2.cvtColor(template, cv2.COLOR_BGRA2GRAY)
template_w, template_h = template_gray.shape[::-1]
with mss.mss() as sct:
# Part of the screen to capture
monitor = {"top": 523, "left": 247, "width": 875, "height": 679}
while True:
last_time = time.time()
# Get raw pixels from the screen, save it to a Numpy array
img = numpy.array(sct.grab(monitor))
# Display the picture
cv2.imshow("Normal", img)
# Display the picture in grayscale
img_gray = cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY)
res = cv2.matchTemplate(
image = img_gray,
templ = template_gray,
method= cv2.TM_CCOEFF_NORMED
)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
#threshold
if max_val >= 0.5:
img = cv2.rectangle(
img = img,
pt1 = max_loc,
pt2 = (
max_loc[0] + template_w, # = pt2 x
max_loc[1] + template_h # = pt2 y
),
color = (0,255,0),
thickness = 3 #fill the rectangle
)
print("fps: {}".format(1 / (time.time() - last_time)))
# Press "q" to quit
if cv2.waitKey(25) & 0xFF == ord("q"):
cv2.destroyAllWindows()
break
I spent three days trying to figure it out, and the only similar code that works but with a poor frame rate is this one:
#imports
from re import template
import cv2
import pyautogui
from time import sleep
#No cooldown time
pyautogui.PAUSE = 0
#template and dimensions
template = cv2.imread("b1.png")
template_gray = cv2.cvtColor(template, cv2.COLOR_RGB2GRAY)
template_w, template_h = template_gray.shape[::-1]
# game window dimensions
x, y, w, h = 523, 247, 875, 679
#wait
sleep(3)
#main
while True:
#screenshot = img
pyautogui.screenshot("image.png", (x, y, w, h))
image = cv2.imread("image.png")
while True:
image_gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
result = cv2.matchTemplate(
image = image_gray,
templ = template_gray,
method = cv2.TM_CCOEFF_NORMED
)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
#threshold
if max_val >= 0.1:
#pyautogui.click(
# x = max_loc[0] + x, #screen x
# y = max_loc[1] + y #screen y
#)
image = cv2.rectangle(
img = image,
pt1 = max_loc,
pt2 = (
max_loc[0] + template_w, # = pt2 x
max_loc[1] + template_h # = pt2 y
),
color = (0,0,255),
thickness = -1 #fill the rectangle
)
else:
break
The structure looks similar the only difference in this template is that it uses pyautogui with OpenCV, whereas I'm trying to use mss. So does that mean that the issue in the code is that there's no physical location of the screen capture due? If so, does that mean it's impossible to make an object detection with mss?? You would make my day if you could disclose this mystery with the code!!
UPD: I was able to solve this, honey! So the issue was that firstly I misspelled the .png file, and to see it detecting an object, place the cv2.imshow after the if statement. Although it works, it's not perfect, so I'm trying to implement the usage of cv2.Canny() but now I don't get any output, so here I'm rising a question of whether there should be a different approach when Canny is used:
import time
import Options.settings as set
import time
import pyautogui as pt
from time import sleep
import cv2
import mss
import numpy
x = 0
offset = set.offset
create_logs = set.create_logs
#template and dimensions
template = cv2.imread("m2.png")
template_gray = cv2.cvtColor(template, cv2.COLOR_BGRA2GRAY)
template_canny = cv2.Canny(template_gray, 79, 100)
template_w, template_h = template_canny.shape[::-1]
with mss.mss() as sct:
# Part of the screen to capture
monitor = {"top": 523, "left": 1600, "width": 230, "height": 359}
while True:
last_time = time.time()
# Get raw pixels from the screen, save it to a Numpy array
img = numpy.array(sct.grab(monitor))
# Display the picture
cv2.imshow("Normal", img)
# Display the picture in grayscale
img_gray = cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY)
img_canny = cv2.Canny(img_gray, 100, 115)
res = cv2.matchTemplate(
image = img_canny,
templ = template_canny,
method= cv2.TM_CCOEFF_NORMED
)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
#threshold
if max_val >= 0.6:
x = x + 1
print(f'{x} is detected')
img = cv2.rectangle(
img = img,
pt1 = max_loc,
pt2 = (
max_loc[0] + template_w, # = pt2 x
max_loc[1] + template_h # = pt2 y
),
color = (0,255,0),
thickness = 3 #fill the rectangle
)
# Display the picture
cv2.imshow("Normal", img)
#print("fps: {}".format(1 / (time.time() - last_time)))
# Press "q" to quit
if cv2.waitKey(25) & 0xFF == ord("q"):
cv2.destroyAllWindows()
break
UPD 2:
As #fmw42 suggested, I tried different OpenCV methods, but whether I try them, they constantly react if there's an object in the screen capture field no matter how I change the if max_vol >= ...
Please find attached
m2.png = https://ibb.co/Xb5tCPZ
Example of what the screen capture look like = https://ibb.co/Xb5tCPZ
alright, somehow, I get the idea behind the issue,
I had to move after the if function and now it's working^^
# Display the picture
cv2.imshow("Normal", img)

How to better crop and paste an image in PIL

I am trying to crop an avatar and place it in a given location in another image using python pil.
Here is the output of what I have so far:
And here is the code:
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
import textwrap
text = "Creating Twitter Cards dynamically with Python"
background_image = "data/obi-pvc.png" # this is the background
avatar = Image.open("data/avatar.png")
font = "data/fonts/AllertaStencil-Regular.ttf"
background = Image.open(background_image)
background_width, background_height = background.size
avatar.convert('RGBA')
## DO NOT change below this line!!
save_name = f"{text.lower().replace(' ', '_')}.png"
#textwrapped = textwrap.wrap(text, width=text_wrap_width)
# crop avatar
width, height = avatar.size
x = (width - height)//2
avatar_cropped = avatar.crop((x, 0, x+height, height))
width_cr, height_cr = avatar_cropped.size
# create grayscale image with white circle (255) on black background (0)
mask = Image.new('L', avatar_cropped.size)
mask_draw = ImageDraw.Draw(mask)
width, height = avatar_cropped.size
mask_draw.ellipse((0, 0, width, height), fill=255)
# add mask as alpha channel
avatar_cropped.putalpha(mask)
draw = ImageDraw.Draw(background)
font = ImageFont.truetype(font, font_size)
draw.text((offset,margin), '\n'.join(textwrapped), font=font, fill=color)
x, y = avatar_cropped.size
margin = 40
# left top
position_tl = (0 + margin, 0 + margin)
position_tr = (x - margin - width_cr, 0 + margin)
position_bl = (0 + margin, y - margin - height_cr)
position_br = (x - margin - width_cr, y - margin - height_cr)
background.paste(avatar_cropped, position)
background.save(f"data/output/{save_name}")
display(background)
The avatar should fit within the circle. I can't seem to really figure out how to apply the positioning. Thanks
Here is the avatar:

Opencv detects pupil but im trying to detect the iris from stock images online

output
input
I'm trying to isolate the iris but the pupil gets isolated in a circle, how can I change it so it surrounds the iris and not the pupil. Also i using stock jpeg files. I tried a lot of stuff but I'm really new to opencv and image processing so any help would be admirable. Also in some images it makes a circle in very weird places which makes me think something else is also up with the code.
#import numpy
import cv2
import numpy as np
class pupil_detection():
def __init__(self, image_path):
'''
initialize the class and set the class attributes
'''
self._img = None
self._img_path = image_path
self._pupil = None
self._centroid = None
def load_image(self):
'''
load the image based on the path passed to the class
it should use the method cv2.imread to load the image
it should also detect if the file exists
'''
self._img = cv2.imread(self._img_path)
#self._img = cv2.resize(self._img, (300,300))
# If the image doesn't exists or is not valid then imread returns None
if type(self._img) == None:
return False
else:
return True
def show_image (self,img):
cv2.imshow("Result",img)
cv2.waitKey(0)
def centroid (self):
# convert image to grayscale image
gray_image = cv2.cvtColor(self._img, cv2.COLOR_BGR2GRAY)
# convert the grayscale image to binary image
ret,thresh = cv2.threshold(gray_image,127,255,0)
# calculate moments of binary image
M = cv2.moments(thresh)
# calculate x,y coordinate of center
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
self._centroid = (cX,cY)
cv2.circle(self._img, (cX, cY), 5, (255, 255, 255), -1)
def detect_pupil (self):
dst = cv2.fastNlMeansDenoisingColored(self._img,None,10,10,7,21)
blur = cv2.GaussianBlur(dst,(5,5),0)
inv = cv2.bitwise_not(blur)
thresh = cv2.cvtColor(inv, cv2.COLOR_BGR2GRAY)
kernel = np.ones((2,2),np.uint8)
erosion = cv2.erode(thresh,kernel,iterations = 1)
ret,thresh1 = cv2.threshold(erosion,210,255,cv2.THRESH_BINARY)
cnts, hierarchy = cv2.findContours(thresh1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
flag = 10000
final_cnt = None
for cnt in cnts:
(x,y),radius = cv2.minEnclosingCircle(cnt)
distance = abs(self._centroid[0]-x)+abs(self._centroid[1]-y)
if distance < flag :
flag = distance
final_cnt = cnt
else:
continue
(x,y),radius = cv2.minEnclosingCircle(final_cnt)
center = (int(x),int(y))
radius = int(radius)
cv2.circle(self._img,center,radius,(255,0,0),2)
self._pupil = (center[0],center[1],radius)
self.show_image(self._img)
def start_detection(self):
if(self.load_image()):
self.centroid()
self.detect_pupil()
else:
print('Image file "' + self._img_path + '" could not be loaded.')
id = pupil_detection(r'rightlook2.jpg')
id.start_detection()

Remove white background from image with opencv python

I have been trying to remove background from a logo and use it as a watermark on product images.I tried to remove background from logo with masking but it also removing black fonts from logo. i need help in removing background without changing the logo. images are attached below. output image is the image i get as output with this code.
logo image: https://drive.google.com/file/d/1yMG6cDuPt8q3EqOJ4Amzp_czWq5hrGS5/view?usp=sharing
product image: https://drive.google.com/file/d/13SmkTgBtWD3yIJq-qGI0aZJ-hjaLbyuB/view?usp=sharing
output image: https://drive.google.com/file/d/1k-fQ9tPUEJKQXPdmdB2ajtliAAG4irNs/view?usp=sharing
this is my code
import cv2
import numpy as np
img = cv2.imread('images/1L2Z3A443AAMC.jpg')
logo = cv2.imread('water2.png')
logo = cv2.resize(logo,(int(img.shape[0]/1.2),int(img.shape[1]/2)))
logo_gray = cv2.cvtColor(logo,cv2.COLOR_BGR2GRAY)
ret,mask= cv2.threshold(logo_gray,245,255,cv2.THRESH_BINARY)
mask_inv = cv2.bitwise_not(mask)
logo_final = cv2.bitwise_and(logo,logo, mask=mask_inv)
h_img,w_img,_ = img.shape
h_logo,w_logo,_ = logo.shape
center_y = int(h_img/2)
center_x = int(w_img/2)
top_y = center_y - (int(h_logo/2))
left_x = center_x - (int(w_logo/2))
bottom_y = top_y + h_logo
right_x = left_x + w_logo
roi = img[top_y:bottom_y,left_x:right_x]
result = cv2.addWeighted(roi,1,logo_final,1,0)
img[top_y:bottom_y,left_x:right_x] = result
cv2.imwrite('sample.jpg',img)
In order to remove the background from a logo. We need to used masking. A masking for the foreground and another masking for the background.
logo = cv2.imread("water2.png", -1)
logo_mask = logo[:,:,3]
logo_mask_inv = cv2.bitwise_not(logo_mask)
logo = logo[:,:,0:3]
logo_background = cv2.bitwise_and(roi, roi, mask=logo_mask_inv)
logo_foreground = cv2.bitwise_and(logo, logo, mask=logo_mask)
final_logo = cv2.add(logo_background, logo_foreground)

PIL image rotation and background issue

I am trying to rotate my transparent gif using the PIL rotate() but I am getting a diamond after rotating it.
Similar problems on SO were solved by using
transparency = img.info['transparency']
img.save('result.gif',transparency=transparency)
or by using
img.save('result.gif', **img.info)
But I am getting the following results as in the images.
My code is
from PIL import Image
file = 'change2_1.gif'
with Image.open(file) as im:
transparency = im.info['transparency']
img = im.rotate(45, expand=True)
img.save('result.gif', transparency=transparency)
Post edited: Try to use this to make black backgroud transparent
from PIL import Image
img = Image.open('img.png')
img = img.convert("RGBA")
datas = img.getdata()
with Image.open(file) as im:
transparency = im.info['transparency']
img = im.rotate(90, expand=True)
img.save('result.gif', transparency=transparency)
newData = []
for item in datas:
if item[0] == 0 and item[1] == 0 and item[2] == 0:
newData.append((255, 255, 255, 0))
else:
newData.append(item)
To avoid having a black frame after rotation, simply change the default mode ('RGB') to 'RGBA' after opening :
img = Image.open('image.png').convert('RGBA')
img.rotate(90, expand = True)

Categories