Created
January 19, 2011 14:07
-
-
Save vim13/786203 to your computer and use it in GitHub Desktop.
Twitterのtimeline上の画像をOpenCVの顔検出にかける
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
#vim:fileencoding=utf-8 | |
import urllib2 | |
import yaml | |
import twitter | |
import re | |
import sys | |
import hashlib | |
import os | |
from opencv.cv import * | |
from opencv.highgui import * | |
class Makehtml: | |
def makehtml(self, lists, flag): | |
head = '''<html> | |
<head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> | |
<title>%sFACEPICK</title> | |
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script> | |
<script type="text/javascript" src="jquery.dimensions.min.js"></script> | |
<script type="text/javascript" src="jquery.lazyload.js"></script> | |
<script type="text/javascript"> | |
$(function() { | |
$("img").lazyload(); | |
}); | |
</script> | |
</head> | |
<body style="background-color:#FFFFFF">''' % (flag) | |
if flag == 'NO': | |
head += '<h1><a href="facepick.html"><font color="#000000">NOFACEPICK<font></a></h1>' | |
else: | |
head += '<h1><a href="nofacepick.html"><font color="#EEEEEE">NO</font></a>FACEPICK</h1>' | |
imgs = '' | |
for s in lists: | |
if re.search('twitpic-', s): | |
ids = re.search('twitpic-([a-z0-9]+)',s).group(1) | |
img = '<a href="http://twitpic.com/%s"><img src="http://twitpic.com/show/thumb/%s" /></a>' % (ids, ids) | |
if re.search('yfrog-', s): | |
ids = re.search('yfrog-([a-z0-9]+)',s).group(1) | |
img = '<a href="http://yfrog.com/%s"><img src="http://yfrog.com/%s.th.jpg" /></a>' % (ids, ids) | |
if re.search('movapic-', s): | |
ids = re.search('movapic-([a-z0-9]+)',s).group(1) | |
img = '<a href="http://movapic.com/pic/%s"><img src="http://image.movapic.com/pic/s_%s.jpeg" /></a>' % (ids, ids) | |
if re.search('instagr-', s): | |
ids = re.search('instagr-([a-zA-Z0-9]+)',s).group(1) | |
img = '<a href="http://instagr.am/p/%s"><img src="http://instagr.am/p/%s/media/?size=t" /></a>' % (ids, ids) | |
if re.search('picplz-', s): | |
ids = re.search('picplz-([a-zA-Z0-9]+)',s).group(1) | |
img = '<a href="http://picplz.com/%s"><img src="http://picplz.com/%s/thumb" /></a>' % (ids, ids) | |
if re.search('flickr-', s): | |
ids = re.search('flickr-([a-zA-Z0-9]+)',s).group(1) | |
uri = re.search('\?(http://[A-Za-z0-9\'~+\-=_.,/%\?!;:@#\*&\(\)]+)',s).group(1) | |
img = '<a href="http://flic.kr/p/%s"><img src="%s" /></a>' % (ids, uri) | |
imgs += img + ' ' | |
foot = '</body><html>' | |
html = head + imgs + foot | |
return html | |
class FlickrApi: | |
def b58decode(self, s): | |
alphabet = '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ' | |
num = len(s) | |
decoded = 0 | |
multi = 1 | |
for i in reversed(range(0, num)): | |
decoded = decoded + multi * ( alphabet.index( s[i] ) ) | |
multi = multi * len(alphabet) | |
return decoded | |
def flickrApi(self, photo_id, flickr_api_key): | |
dec_photo_id = self.b58decode(photo_id) | |
uri = 'http://www.flickr.com/services/rest?method=flickr.photos.getInfo&format=json&api_key=%s&photo_id=%s' % (flickr_api_key, dec_photo_id) | |
f = urllib2.urlopen(uri).read() | |
farm = re.search('"farm":([0-9])', f).group(1) | |
server = re.search('"server":"([0-9]+)"', f).group(1) | |
my_id = re.search('"id":"([0-9]+)"', f).group(1) | |
secret = re.search('"secret":"([0-9a-z]+)"', f).group(1) | |
res = 'http://farm%s.static.flickr.com/%s/%s_%s.jpg' % (farm, server, my_id, secret) | |
return res | |
class Facepick(Makehtml, FlickrApi): | |
def __init__(self, api, id_file, dump_path, pics_path, html_path, flickr_api_key): | |
self.pics_path = pics_path | |
self.html_path = html_path | |
self.api = api | |
self.id_file = id_file | |
self.dump_path = dump_path | |
self.flickr_api_key = flickr_api_key | |
self.flickr_url = '' | |
def faceDetect(self,imgfile): | |
# 画像を読み込む | |
src_img = cvLoadImage(imgfile, CV_LOAD_IMAGE_COLOR) | |
src_gray = cvCreateImage(cvSize(src_img.width, src_img.height), IPL_DEPTH_8U, 1) | |
# ブーストされた分類器のカスケードを読み込む | |
cascade_name = 'haarcascade_frontalface_default.xml' | |
cascade = cvLoadHaarClassifierCascade(cascade_name, cvSize(1,1)) | |
# メモリを確保し,読み込んだ画像のグレースケール化,ヒストグラムの均一化を行う | |
storage = cvCreateMemStorage(0) | |
cvClearMemStorage(storage) | |
cvCvtColor(src_img, src_gray, CV_BGR2GRAY) | |
cvEqualizeHist(src_gray, src_gray) | |
# 顔検出 | |
faces = cvHaarDetectObjects(src_gray, cascade, storage, 1.11, 4, 0, cvSize(0, 0)) | |
flag = False | |
for c, i in enumerate(faces): | |
flag = True | |
return flag | |
def readFile(self): | |
idfile = open(self.id_file, 'r') | |
latest_id = idfile.readline() | |
idfile.close() | |
return latest_id | |
def writeFile(self, path, text): | |
idfile = open(path, 'w') | |
idfile.write(str(text)) | |
idfile.close() | |
def saveImage(self, s): | |
save_image = file(self.pics_path + s[1] + s[0] + '.jpg', "wb") | |
if s[1] == 'twitpic-': | |
f = urllib2.urlopen('http://twitpic.com/show/full/' + s[0]) | |
if s[1] == 'yfrog-': | |
f = urllib2.urlopen('http://yfrog.com/%s:iphone' % s[0]) | |
if s[1] == 'movapic-': | |
f = urllib2.urlopen('http://image.movapic.com/pic/m_%s.jpeg' % s[0]) | |
if s[1] == 'instagr-': | |
f = urllib2.urlopen('http://instagr.am/p/%s/media/?size=l' % s[0]) | |
if s[1] == 'picplz-': | |
f = urllib2.urlopen('http://picplz.com/%s/thumb/400' % s[0]) | |
if s[1] == 'flickr-': | |
uri = self.flickrApi(s[0], self.flickr_api_key) | |
f = urllib2.urlopen(uri) | |
self.flickr_url = re.sub('\.jpg', '_t.jpg', uri) | |
save_image.write(f.read()) | |
save_image.close() | |
def deleteImage(self, pics): | |
os.remove(self.pics_path + pics + '.jpg') | |
def japanese(self, text): | |
def check_chr(x): | |
return ((x >= 0x3040 and x <= 0x309f) or (x >= 0x30a0 and x <= 0x30ff)) | |
return [ch for ch in text if check_chr(ord(ch))] | |
def getTweet(self): | |
''' | |
#プロフィールから取得 | |
statuses = self.api.GetUserTimeline() | |
''' | |
latest_id = self.readFile() | |
#自分のTimelineから取得 | |
statuses = self.api.GetFriendsTimeline(since_id = latest_id, count = 200) | |
tweets = [s.text for s in statuses] | |
''' | |
#PublicTimelineから取得 | |
statuses = self.api.GetPublicTimeline(since_id = latest_id) | |
tweets = [s.text for s in statuses if s.text and self.japanese(s.text)] | |
''' | |
self.writeFile(self.id_file, statuses[0].id) | |
p = re.compile('twitpic.com/([a-z0-9]+)') | |
twitpic = [(str(p.search(s).group(1)), 'twitpic-') for s in tweets if p.search(s) != None] | |
p = re.compile('yfrog.com/([a-z0-9]+)') | |
yfrog = [(str(p.search(s).group(1)), 'yfrog-') for s in tweets if p.search(s) != None] | |
p = re.compile('movapic.com/pic/([a-z0-9]+)') | |
movapic = [(str(p.search(s).group(1)), 'movapic-') for s in tweets if p.search(s) != None] | |
p = re.compile('instagr.am/p/([a-zA-Z0-9]+)') | |
instagr = [(str(p.search(s).group(1)), 'instagr-') for s in tweets if p.search(s) != None] | |
p = re.compile('picplz.com/([a-zA-Z0-9]+)') | |
picplz = [(str(p.search(s).group(1)), 'picplz-') for s in tweets if p.search(s) != None] | |
p = re.compile('flic.kr/p/([a-zA-Z0-9]+)') | |
flickr = [(str(p.search(s).group(1)), 'flickr-') for s in tweets if p.search(s) != None] | |
return twitpic + yfrog + movapic + instagr + picplz + flickr | |
def main(self): | |
pics = self.getTweet() | |
ok_lists = [] | |
no_lists = [] | |
if pics: | |
for s in pics: | |
self.saveImage(s) | |
imgfile = self.pics_path + s[1] + s[0] + '.jpg' | |
if self.faceDetect(imgfile) == True: | |
if self.flickr_url: | |
ok_lists.append(s[1] + s[0] + '?' + self.flickr_url + '\n') | |
else: | |
ok_lists.append(s[1] + s[0] + '\n') | |
else: | |
#顔判定無い画像を削除 | |
#self.deleteImage(s[0]) | |
if self.flickr_url: | |
no_lists.append(s[1] + s[0] + '?' + self.flickr_url + '\n') | |
else: | |
no_lists.append(s[1] + s[0] + '\n') | |
flag = '' | |
if ok_lists: | |
f = open(self.dump_path + 'dump.txt', 'a+') | |
f.writelines(ok_lists) | |
f.seek(-10000,2) | |
lis = f.readlines() | |
f.close() | |
faces = [s[:-1] for s in lis[-280:]] | |
faces.reverse() | |
html = self.makehtml(faces, flag) | |
path = self.html_path + 'facepick.html' | |
self.writeFile(path, html) | |
if no_lists: | |
flag = 'NO' | |
print no_lists | |
f = open(self.dump_path + 'no.txt', 'a+') | |
a = f.writelines(no_lists) | |
f = open(self.dump_path + 'no.txt', 'r') | |
lis = f.readlines() | |
f.close() | |
lis.reverse() | |
html = self.makehtml(lis, flag) | |
path = self.html_path + 'nofacepick.html' | |
self.writeFile(path, html) | |
if __name__ == '__main__': | |
yaml_file = open('bot.yaml', 'r').read() | |
yam = yaml.load(yaml_file) | |
consumer_key = yam['twitter.com']['consumer_key'] | |
consumer_secret = yam['twitter.com']['consumer_secret'] | |
access_token_key = yam['twitter.com']['access_token_key'] | |
access_token_secret = yam['twitter.com']['access_token_secret'] | |
flickr_api_key = yam['flickr.com']['flickr_api_key'] | |
id_file = yam['file']['id_file'] | |
dump_path = yam['file']['dump_path'] | |
pics_path = yam['file']['pics_path'] | |
html_path = yam['file']['html_path'] | |
api = twitter.Api(consumer_key, consumer_secret, access_token_key, access_token_secret) | |
obj = Facepick(api, id_file, dump_path, pics_path, html_path, flickr_api_key) | |
obj.main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment