|
|
Line 4: |
Line 4: |
|
| |
|
| ==== News Graffiti Twitter Bot ==== | | ==== News Graffiti Twitter Bot ==== |
| | The News Graffiti Twitter Bot places speech bubbles on the images taken from the news accounts on twitter. |
|
| |
|
| [[Image:Screen_Shot_2015-10-19_at_12.30.52_am.png]] | | [[Image:Screen_Shot_2015-10-19_at_12.30.52_am.png]] |
|
| |
|
| | ==== Screen Shot ==== |
|
| |
|
| The News Graffiti Twitter Bot places speech bubbles on the images taken from the news accounts on twitter.
| | [[Image:Screen_Shot_2015-10-19_at_12.32.00_am.png]] |
|
| |
|
| [[Image:Screen_Shot_2015-10-19_at_12.32.00_am.png]]
| |
|
| |
|
|
| |
|
| == code == | | == code == |
|
| |
|
| import cv2
| | [http://pastebin.com/JPw0gKAf link to the code] <br> |
| import numpy as np
| |
| import random
| |
| from twitterbot import TwitterBot
| |
| import PIL
| |
| from PIL import Image, ImageDraw
| |
| from sys import argv
| |
| import os
| |
| | |
| debug = True
| |
| classifier = "haarcascade_frontalface_default.xml"
| |
| faceCascade = cv2.CascadeClassifier(classifier)
| |
| | |
| | |
| def face_detect(image):
| |
| """
| |
| Return rectangles of identified face regions
| |
| """
| |
| | |
| # numpy grayscale image for face detection
| |
| array = np.asarray(image)
| |
| gray_image = cv2.cvtColor(array, cv2.COLOR_BGR2GRAY)
| |
| | |
| # tweak this for better results ..
| |
| | |
| faces = faceCascade.detectMultiScale(
| |
| gray_image,
| |
| scaleFactor=1.1,
| |
| minNeighbors=5,
| |
| minSize=(25, 25),
| |
| flags=cv2.cv.CV_HAAR_SCALE_IMAGE
| |
| )
| |
| | |
|
| |
| # convert boxes from from arrays to tuples
| |
| boxes = [(x, y, x + w, y + h) for (x, y, w, h) in faces]
| |
| return boxes
| |
|
| |
| | |
| def face_mark(image):
| |
| """
| |
| Mark faces with boxes
| |
| """
| |
| | |
| # work on a copy
| |
| image = image.copy()
| |
|
| |
| # identify boxes
| |
| boxes = face_detect(image)
| |
| | |
| # get drawing context for the current image
| |
| ctx = ImageDraw.Draw(image)
| |
| | |
| # define colors
| |
| black = (0, 0, 0, 255)
| |
| white = (255,255,255,255)
| |
| | |
| # draw boxes
| |
| for box in boxes:
| |
| | |
| # draw a black box
| |
| ctx.rectangle(box, fill=None, outline=black)
| |
| | |
| # draw a white box around it
| |
| x1, y1, x2, y2 = box
| |
| box = x1 - 1, y1 - 1, x2 + 1, y2 + 1
| |
| ctx.rectangle(box, fill=None, outline=white)
| |
| | |
| return image, boxes
| |
| | |
| def comic_element(image):
| |
| """
| |
| Pasting Speech Bubbles on the Image
| |
| """
| |
| | |
| #working on a copy of the image
| |
| image = image.copy()
| |
| | |
|
| |
| # face detection
| |
| boxes=face_detect(image)
| |
| | |
| ctx = ImageDraw.Draw(image)
| |
| | |
| # grabing random files of img from the folder of speech bubbles
| |
| directory = os.path.join(os.path.dirname(__file__), "bubbles")
| |
| directory_list = os.listdir('./bubbles/')
| |
| | |
| # For MAC user - this is important step as iOS adds a hidden file called .DS
| |
| directory_list.remove('.DS_Store')
| |
|
| |
|
| |
|
| |
| | |
| #finding the location for speech bubble and pasting it
| |
| for box in boxes:
| |
| | |
|
| |
| | |
| #coordinate for face box
| |
| | |
| x1, y1, x2, y2 = box
| |
| | |
| # taking a random choice from the list created before
| |
| one_bubble = random.choice(directory_list)
| |
| # adding the name of the file on the rute so it can be opend later...
| |
| imgfile = os.path.join(directory, one_bubble)
| |
| | |
| # open the one_bubble img on the boxes
| |
| sBubble= Image.open(imgfile)
| |
| | |
| #resize the img of the bubble
| |
| sBubble = sBubble.resize((160,160), resample=Image.ANTIALIAS)
| |
| xS, yS = sBubble.size
| |
| # Debugging purpose
| |
| #sBubble.show()
| |
| | |
| | |
| # Finding the location for pasting the speech bubble
| |
|
| |
| # Centre Point coordinates
| |
| | |
| cx = int((x2-x1)*0.5)
| |
| # This value is passed to define the box for pasting image and it only takes integer value.
| |
| cy = int((y2-y1)*0.5)
| |
| | |
| # Selecting either right or left side of the face for the bubble placement
| |
| | |
| x_pos = random.choice((x1,x2))
| |
| | |
| if x_pos == x1:
| |
| x_pos = x_pos - xS
| |
| y_pos =yS*(-1)
| |
| else:
| |
| y_pos =yS
| |
| | |
| # Bubble box defines the size and place for pasting speech bubble on face
| |
| bubblebox = (x_pos,cy,x_pos+xS,cy+yS)
| |
| | |
| | |
| #left, upper coordinate
| |
|
| |
| px1 = int(r*np.math.cos(angle))
| |
|
| |
| py1 = int(r*np.math.sin(angle)+yS)
| |
|
| |
| image.paste(sBubble, bubblebox, sBubble)
| |
| #image.show()
| |
|
| |
| return image, boxes
| |
| | |
| | |
| | |
| | |
| if __name__ == '__main__':
| |
| | |
| """
| |
| Loading Image
| |
| """
| |
| src = Image.open("face1.jpg")
| |
| # face detection
| |
| boxes=face_detect(src)
| |
| img,box = comic_element(src)
| |
| img.show()
| |
| img.save("test_img.jpg")
| |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
|
| |
|
|
| |
|