Reputation: 11
I am trying to create an image with the edges replaced with text, similar to This Youtube video thumbnail but from a source image. I've used OpenCV to get a version of a source image with edges, and Pillow to actually write the text, but I'm not sure where to start when it comes to actually manipulating the text automatically to fit to the edges. The code I have so far is:
import cv2 as cv
from matplotlib import pyplot as plt
from PIL import Image, ImageFont, ImageDraw, ImageShow
font = ImageFont.truetype(r"C:\Users\X\Downloads\Montserrat\Montserrat-Light.ttf", 12)
text = ["text", "other text"]
img = cv.imread(r"C:\Users\X\Pictures\picture.jpg",0)
edges = cv.Canny(img,100,200)
img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
im_pil = Image.fromarray(edges)
This code is just for the edge detection and moving the detected edges to Pillow.
Please help
Upvotes: 0
Views: 664
Reputation: 53164
I am not sure where the "edges" comes in from the canny edge detector.
However, the circular text wrap can be done very simply in Python/Wand that uses ImageMagick. Or one can do that in Python/OpenCV using cv2.remap and custom transformation maps.
Input:
1. Python Wand
(output size determined automatically from input size)
from wand.image import Image
from wand.font import Font
from wand.display import display
with Image(filename='some_text.png') as img:
img.background_color = 'white'
img.virtual_pixel = 'white'
# 360 degree arc, rotated 0 degrees
img.distort('arc', (360,0))
img.save(filename='some_text_arc.png')
img.format = 'png'
display(img)
Result:
2. Python/OpenCV
import numpy as np
import cv2
import math
# read input
img = cv2.imread("some_text.png")
hin, win = img.shape[:2]
win2 = win / 2
# specify desired square output dimensions and center
hout = 100
wout = 100
xcent = wout / 2
ycent = hout / 2
hwout = max(hout,wout)
hwout2 = hwout / 2
# set up the x and y maps as float32
map_x = np.zeros((hout, wout), np.float32)
map_y = np.zeros((hout, wout), np.float32)
# create map with the arc distortion formula --- angle and radius
for y in range(hout):
Y = (y - ycent)
for x in range(wout):
X = (x - xcent)
XX = (math.atan2(Y,X)+math.pi/2)/(2*math.pi)
XX = XX - int(XX+0.5)
XX = XX * win + win2
map_x[y, x] = XX
map_y[y, x] = hwout2 - math.hypot(X,Y)
# do the remap this is where the magic happens
result = cv2.remap(img, map_x, map_y, cv2.INTER_CUBIC, borderMode = cv2.BORDER_CONSTANT, borderValue=(255,255,255))
# save results
cv2.imwrite("some_text_arc.jpg", result)
# display images
cv2.imshow('img', img)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Result:
Upvotes: 2
Reputation: 54812
Neither OpenCV nor PIL has a way to do that, but you can use ImageMagick. How to warp an image to take shape of path with python?
Upvotes: 0