Project

General

Profile

« Previous | Next » 

Revision b6f0d860

Added by dsorber over 12 years ago

Whoops I need to use the move command so that git keeps track of where things have gone.

View differences:

software/bashquote/bashquote
#!/usr/bin/env python
import cPickle
import os
import random
import sys
BQ_DIR = '/Users/dsorber/.bashquote'
BQ_CACHE = '/Users/dsorber/.bashquote/bq_cache'
def main():
# Create the cache file, or open it if it already exists
if not os.path.exists(BQ_CACHE):
print 'bashquote cache does not exist!'
sys.exit()
else :
cache = open(BQ_CACHE, 'r')
quotes = cPickle.load(cache)
cache.close()
# Choose a random quote from the list
num_quotes = len(quotes)
if num_quotes == 1:
# Repopulate the list manually if there is only one quote remaining
print 'Low on quotes, grabbing some more...',
os.system('bashquote_populate')
print 'Done'
index = random.randint(0, num_quotes - 1)
quote = quotes.pop(index)
# Print it out
print 'bashquote #%s ------ %s' % (quote[0], quote[1])
print quote[2]
# Re-store the remaining quotes and exit
cache = open(BQ_CACHE, 'w')
cPickle.dump(quotes, cache, -1)
cache.close()
sys.exit()
if __name__=="__main__":
main()
software/bashquote/bashquote_populate
#!/usr/bin/env python
import cPickle
import os
import re
import sys
import urllib
BQ_DIR = '/Users/dsorber/.bashquote'
BQ_CACHE = '/Users/dsorber/.bashquote/bq_cache'
def main():
# Create a list to hold the quotes
quotes = []
# Create the bashquote directory if it does not exist
if not os.path.exists(BQ_DIR):
print 'Creating bashquote directory...',
os.mkdir(BQ_DIR)
print 'Done'
# Create the cache file, or open it if it already exists
if not os.path.exists(BQ_CACHE):
print 'Creating bashquote cache...',
cache = open(BQ_CACHE, 'w')
cache.close()
print 'Done'
else:
cache = open(BQ_CACHE, 'r')
quotes = cPickle.load(cache)
cache.close()
# Only grab fresh quotes if there are less than 50 in the cache
if not len(quotes) < 50:
print 'plenty left'
sys.exit()
# Goto to the random >0 bash quotes page
listpage = urllib.urlopen("http://www.bash.org/?random1")
listpagetext = listpage.read()
quote_regex = '<p class="quote".+<b>#(\d+)</b>.+</a>\((\d+)\)<a .+<p class="qt">([\s\S]+?)</p>'
quotes = []
for quote_match in re.finditer(quote_regex, listpagetext):
quotes.append((quote_match.group(1),
quote_match.group(2),
unhtmlify(quote_match.group(3))))
# Store the list of quotes in the cache file, using the highest protocol
cache = open(BQ_CACHE, 'w')
cPickle.dump(quotes, cache, -1)
cache.close()
sys.exit()
def unhtmlify(quote):
# Filter out that HTML bullshit
return quote.replace("&lt;", "<").replace("\'&lt;", "<")\
.replace("&gt;", ">").replace("&quot;", "\"")\
.replace("&nbsp;", " ").replace("\\'", "'")\
.replace("\\x92", "'").replace("<br />\\r\\n', '", "\n")\
.replace("<br />\\r\\n\", '", "\n").replace("&amp;", "&")\
.replace("<br />\\r\\n', \"", "\n")\
.replace("<br />\\r\\n\", \"", "\n").replace("<br />", "")
if __name__=="__main__":
main()
software/image_grabber/grabber.py
from multiprocessing import Process
from multiprocessing import Queue
import multiprocessing
import os
import re
import sys
import time
import urllib2
# --- DESCRIPTION ---
# A script for circumventing the image "protection" from http://celebforum.to/
# specifically for imagevenue.com links (will also support imagebam in the future)
#
# USAGE:
# python grabber.py <html source of gallery>
# http://img184.imagevenue.com/loc663/th_74708_0005_blood_orange_dress05_123_663lo.jpg
# http://img184.imagevenue.com/img.php?loc=loc663&image=74708_0005_blood_orange_dress05_123_663lo.jpg
IMAGEVENUE_PAGE_RE = r'"http://(img\d{3})\.imagevenue\.com/(loc\d{3})/(.+?\.jpg)"'
IMAGEVENUE_SRC_RE = r'<img id="thepic" .+? SRC="(.+?)"'
IMAGEBAM_PAGE_RE = r'"http://thumbnails\d+\.imagebam\.com/\d+/(.+?\.jpg)"'
IMAGEBAM_SRC_RE = r'<img .+? onclick="scale\(this\);" src="(.+?\.jpg)"'
# Location where the images should be saved
IMAGE_SAVE_PATH = 'images'
class ImageVenueProcessor(Process):
def __init__(self, input_file_name, image_src_queue):
Process.__init__(self)
self.input_file_name = input_file_name
self.image_src_queue = image_src_queue
self.running = False
def run(self):
self.running = True
# Iterate over the input source file and look for all thumbnail image matches
matches = []
with open(self.input_file_name, 'r') as input_file:
for line in input_file:
line_matches = re.findall(IMAGEVENUE_PAGE_RE, line)
for line_match in line_matches:
matches.append(line_match)
# Iterate over each match and build the correct image page URL
# Major thanks to http://vintage-erotica-forum.com/showthread.php?p=694632
# for explaining the secret sauce!
total = len(matches)
for idx, match in enumerate(matches):
server = 'http://{:s}.imagevenue.com/'.format(match[0])
image_name = match[2][3:]
image_loc = 'img.php?loc={:s}&image={:s}'.format(match[1], image_name)
link = '{:s}{:s}'.format(server, image_loc)
# Open the image page and download the source HTML
response = urllib2.urlopen(link)
html = response.read()
# Iterate over the source HTML looking for the image source link
for line in html.split('\n'):
img = re.search(IMAGEVENUE_SRC_RE, line)
if img:
location = '{:s}{:s}'.format(server, img.group(1))
print '{:3d} of {:3d} - {:s}'.format(idx + 1, total, location)
self.image_src_queue.put(location)
self.running = False
class ImageBamProcessor(Process):
def __init__(self, input_file_name, image_src_queue):
Process.__init__(self)
self.input_file_name = input_file_name
self.image_src_queue = image_src_queue
self.running = False
def run(self):
self.running = True
# Iterate over the input source file and look for all thumbnail image matches
matches = []
with open(self.input_file_name, 'r') as input_file:
for line in input_file:
line_matches = re.findall(IMAGEBAM_PAGE_RE, line)
for line_match in line_matches:
matches.append(line_match)
# Iterate over each match and build the correct image page URL
# Thanks to http://board.jdownloader.org/showthread.php?t=26255
total = len(matches)
for idx, match in enumerate(matches):
image_name = match
server = 'http://www.imagebam.com/image/'
link = '{:s}{:s}'.format(server, image_name)
# Open image page and download the source HTML
response = urllib2.urlopen(link)
html = response.read()
# Iterate over the source HTML looking for the image source link
for line in html.split('\n'):
img_match = re.search(IMAGEBAM_SRC_RE, line)
if img_match:
location = img_match.group(1)
print '{:3d} of {:3d} - {:s}'.format(idx + 1, total, location)
self.image_src_queue.put(location)
self.running = False
class Downloader(Process):
def __init__(self, image_src_queue):
Process.__init__(self)
self.image_src_queue = image_src_queue
def run(self):
while True:
image_path = self.image_src_queue.get()
image_name = image_path.rsplit('/', 1)[1]
print 'Downloading "{:s}"...'.format(image_path),
# Check if the image has already been downloaded before
# attempting to download it
contents = os.listdir(IMAGE_SAVE_PATH)
if image_name not in os.listdir(IMAGE_SAVE_PATH):
# Download the freakin image!
try:
response = urllib2.urlopen(image_path, timeout=4)
data = response.read()
except:
# print 'Unable to download: {:s}'.format(location)
print 'ERROR'
continue
# Save the image to the desired location
with open(os.path.join(IMAGE_SAVE_PATH, image_name), 'wb') as new_image:
new_image.write(data)
print 'DONE'
else:
print 'SKIPPED'
def main():
if len(sys.argv) < 2:
print 'Not enough arguments specified!'
return -1
# Create the image source queue that the "Processing" objects will produce
# to and the "Downloader" objects will consume from
image_src_queue = Queue(2048)
# Based on the number of cores in the system determine how many
# Downloader worker objects should be created
num_workers = max(1, multiprocessing.cpu_count() - 2)
# Create the Downloader worker objects
dl_workers = []
for ctr in xrange(num_workers):
dl_worker = Downloader(image_src_queue)
dl_worker.start()
dl_workers.append(dl_worker)
# Create the ImageBam Processsor
ib_proc = ImageBamProcessor(sys.argv[1], image_src_queue)
ib_proc.start()
# Create the ImageVenue Processor
iv_proc = ImageVenueProcessor(sys.argv[1], image_src_queue)
iv_proc.start()
# Wait for the Processor objects to complete
ib_proc.join()
iv_proc.join()
# Wait until the image source queue is empty, then kill all the
# Downloader workers
while True:
if image_src_queue.empty():
# Wait 3 seconds to allow any downloads to finish
time.sleep(3)
for dl_worker in dl_workers:
dl_worker.terminate()
break
print '\n\n'
if __name__ == '__main__':
sys.exit(main())
software/keypress counter/keypress_counter.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <dirent.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/time.h>
#include <termios.h>
#include <signal.h>
void perror_exit(char *error)
{
perror(error);
printf("\nexiting...(%d)\n", 9);
exit(0);
}
int main(int argc, char *argv[])
{
uint32_t counter;
struct input_event ev[64];
int fd, rd, value;
int size = sizeof(struct input_event);
char name[256] = "Unknown";
char *device = NULL;
FILE *out_file;
// Make sure the user is root
if ((getuid ()) != 0)
{
printf ("\nYou must be root to display keypress counts.\n\n");
exit(0);
}
// Setup check
if (argv[1] == NULL)
{
printf("Please specify (on the command line) the path to the dev event interface device\n");
exit(0);
}
if (argc > 1)
{
device = argv[1];
}
if (argc > 2)
{
out_file = fopen(argv[2], "w");
if (out_file == NULL)
{
printf("Unable to open file %s", argv[2]);
exit(0);
}
}
// Open specified device
if ((fd = open (device, O_RDONLY)) == -1)
{
printf("%s is not a vaild device.\n", device);
exit(0);
}
// Print device name
//ioctl (fd, EVIOCGNAME(sizeof(name)), name);
//printf ("Reading From : %s (%s)\n", device, name);
// Main loop, read
counter = 0;
while(1)
{
if ((rd = read(fd, ev, size * 64)) < size)
{
perror_exit("read()");
}
value = ev[0].value;
// Only read the key press event
if (value != ' ' && ev[1].value == 1 && ev[1].type == 1)
{
counter++;
// If a filename was given, output to that file
if (argc > 2)
{
// Seek to beginning of file, output and flush to file
fseek(out_file, 0, SEEK_SET);
fprintf(out_file, "%10u", counter);
fflush(out_file);
}
else
{
// Otherwise print to stdout
// Print count, fixed width of 10 spaces, over of the same line
printf("\r%10u", counter);
fflush(stdout);
}
// Check for (hopefully rare) overflow condition
if (counter == UINT32_MAX)
{
printf("\nGADZOOKS BATMAN!!! You overflowed a 32 bit unsigned integer with all your keystrokes!\n\n");
counter = 0;
}
}
}
fclose(out_file);
return 0;
}
software/keypress counter/keypress_wrapper.sh
#!/bin/bash
#
# Keypress counter wrapper
#
./keypress_counter /dev/input/by-path/platform-i8042-serio-0-event-kbd /home/dsorber/Desktop/keypress_count.txt &
KC_PID=$!
echo $KC_PID
sleep 30s
echo "`date +%F` `cat /home/dsorber/Desktop/keypress_count.txt`" >> keypress_totals.txt
kill -15 `echo $KC_PID`
./keypress_counter /dev/input/by-path/platform-i8042-serio-0-event-kbd /home/dsorber/Desktop/keypress_count.txt &
KC_PID=$!
echo $KC_PID
sleep 30s
echo "`date +%F` `cat /home/dsorber/Desktop/keypress_count.txt`" >> keypress_totals.txt
kill -15 `echo $KC_PID`
./keypress_counter /dev/input/by-path/platform-i8042-serio-0-event-kbd /home/dsorber/Desktop/keypress_count.txt &
KC_PID=$!
echo $KC_PID
sleep 30s
echo "`date +%F` `cat /home/dsorber/Desktop/keypress_count.txt`" >> keypress_totals.txt
kill -15 `echo $KC_PID`
software/misc/popcount_alg.py
import sys
def popcount(i):
i = i - ((i >> 1) & 0x55555555)
i = (i & 0x33333333) + ((i >> 2) & 0x33333333)
return ((((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) & 0xFFFFFFFF) >> 24
def main():
print 'Popcount Algorithm Overview\n'
#i = i - ((i >> 1) & 0x55555555);
#i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
#return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
uint = raw_input('Enter a 32 bit unsigned number> ')
if uint.startswith('0x'):
uint = int(uint, 16) & 0xFFFFFFFF
else:
uint = int(uint) & 0xFFFFFFFF
print
#i = i - ((i >> 1) & 0x55555555);
print 'Step 0: Input number: {:>10d} -- hex: 0x{:08X}'.format(uint, uint)
op_step1 = (uint >> 1)
print 'Step 1: (i >> 1): {:>10d} -- hex: 0x{:08X}'.format(op_step1, op_step1)
op_step2 = op_step1 & 0x55555555
print 'Step 2: ((i >> 1) & 0x55555555): {:>10d} -- hex: 0x{:08X}'.format(op_step2, op_step2)
op_step3 = uint - op_step2
print 'Step 3: i - ((i >> 1) & 0x55555555): {:>10d} -- hex: 0x{:08X}'.format(op_step3, op_step3)
print
#i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
op_step4 = op_step3 & 0x33333333
print 'Step 4: (i & 0x33333333): {:>10d} -- hex: 0x{:08X}'.format(op_step4, op_step4)
op_step5 = op_step3 >> 2
print 'Step 5: (i >> 2): {:>10d} -- hex: 0x{:08X}'.format(op_step5, op_step5)
op_step6 = op_step5 & 0x33333333
print 'Step 6: ((i >> 2) & 0x33333333): {:>10d} -- hex: 0x{:08X}'.format(op_step6, op_step6)
op_step7 = op_step4 + op_step6
print 'Step 7: (i & 0x33333333) + ((i >> 2) & 0x33333333): {:>10d} -- hex: 0x{:08X}'.format(op_step7, op_step7)
print
#ans = (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24
op_step8 = op_step7 >> 4
print 'Step 8: (i >> 4): {:>10d} -- hex: 0x{:08X}'.format(op_step8, op_step8)
op_step9 = op_step7 + op_step8
print 'Step 9: (i + (i >> 4)): {:>10d} -- hex: 0x{:08X}'.format(op_step9, op_step9)
op_step10 = op_step9 & 0x0F0F0F0F
print 'Step 10: ((i + (i >> 4)) & 0x0F0F0F0F): {:>10d} -- hex: 0x{:08X}'.format(op_step10, op_step10)
op_step11 = (op_step10 * 0x01010101) & 0xFFFFFFFF
print 'Step 11: (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101): {:>10d} -- hex: 0x{:08X}'.format(op_step11, op_step11)
op_step12 = op_step11 >> 24
print 'Step 12: (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24: {:>10d} -- hex: 0x{:08X}'.format(op_step12, op_step12)
print
print 'Popcount: {:d}'.format(popcount(uint))
if __name__ == '__main__':
sys.exit(main())
software/misc/unbruce.py
import os
import sys
def main():
for file in os.listdir(sys.argv[1]):
if file.startswith('www-bruce-juice-com-') or \
file.startswith('www-bruce-juice-com_'):
print '%s ---> %s' % (file, file[20:])
os.rename(file, file[20:])
elif file.startswith('www-bangtidy-net-') or \
file.startswith('www-bangtidy-net_'):
print '%s ---> %s' % (file, file[17:])
os.rename(file, file[17:])
if __name__ == '__main__':
sys.exit(main())
software/renamer/renamer.py
import os
import re
import sys
def main():
if len(sys.argv) < 3:
print 'Not enough arguments specified!'
return
show_name = sys.argv[1]
directory = sys.argv[2]
show_name = show_name.replace(' ', '\.')
for filename in os.listdir(directory):
m = re.match("^(%s)\.S(\d+)E(\d+)\.(.*)\.(\w{3})$" % show_name, filename, re.IGNORECASE)
if m:
new_name = '%s - S%sE%s.%s' % (show_name.replace('\.', ' '),
m.group(2), m.group(3), m.group(5).lower())
print '%s --- MATCH: %s' % (filename, new_name)
os.rename(os.path.join(directory, filename),
os.path.join(directory, new_name))
else:
print filename
if __name__ == '__main__':
sys.exit(main())
software/similar images/build_index.py
#!/opt/local/bin/python2.7
import bz2
import cPickle
import imghdr
import os
import sys
import pHash
from image import Image
# Build index
# TODO: write more schtuff here
def main():
image_list = []
# Make sure at least one command line argument was provided
if len(sys.argv) < 2:
print 'Usage: build_index.py <path>'
return -1;
# Print out the path we're walking
path = sys.argv[1]
print 'Building image index from path: {:s}\n'.format(path)
# Walk the root path and count all images
img_counter = 0
for root, dirs, files in os.walk(path):
for file in files:
img_path = os.path.join(root, file)
# Check the make sure the file is a JPEG
if not imghdr.what(img_path) == 'jpeg':
continue
img_counter += 1
print 'Done counting, {:d} images total.'.format(img_counter)
# Walk the root path
ctr = 0
for root, dirs, files in os.walk(path):
for file in files:
img_path = os.path.join(root, file)
# Check the make sure the file is a JPEG
if not imghdr.what(img_path) == 'jpeg':
continue
ctr += 1
percent_done = int((float(ctr) / img_counter) * 100)
print '{:3d}% -- {:s}'.format(percent_done, img_path)
img_obj = Image(img_path)
# print '{:s} -> {:016X}'.format(img_path, img_obj.hash)
image_list.append(img_obj)
# Write index as a bzip2'd file to save space
index_file = bz2.BZ2File('images_index.bz2', 'w')
cPickle.dump(image_list, index_file)
index_file.close()
print '\nIndex file images_index.bz2 created. Done.'
if __name__ == '__main__':
sys.exit(main())
software/similar images/build_index_faster.py
#!/opt/local/bin/python2.7
import bz2
import cPickle
import imghdr
import math
import multiprocessing
import os
import Queue
import random
import sys
import pHash
from image import Image
NUM_WORKERS = 7
# Build index
# TODO: write more schtuff here
class IndexWorker(multiprocessing.Process):
def __init__(self, file_list, queue):
multiprocessing.Process.__init__(self)
self.file_list = file_list
self.queue = queue
def run(self):
list_size = len(self.file_list)
ctr = 0
for file_path in self.file_list:
ctr += 1
percent_done = int((float(ctr) / list_size) * 100)
# We can only index jpegs right now
if not imghdr.what(file_path) == 'jpeg':
continue
print '{:d} -- {:3d}% -- {:s}'.format(self.pid, percent_done,
file_path)
image_obj = Image(file_path)
self.queue.put(image_obj, True)
def main():
# Make sure at least one command line argument was provided
if len(sys.argv) < 2:
print 'Usage: build_index_faster.py <path>'
return -1;
# Print out the path we're walking
path = sys.argv[1]
print 'Building image index from path: {:s}\n'.format(path)
master_file_list = []
image_index = []
# Walk the root path and create a list of all files in the root path
for root, dirs, files in os.walk(path):
for file in files:
master_file_list.append(os.path.join(root, file))
random.shuffle(master_file_list)
print 'Done counting, {:d} files total.'.format(len(master_file_list))
workers = []
queue = multiprocessing.Queue(64)
def chunker(seq, size):
return (seq[pos:pos + size] for pos in xrange(0, len(seq), size))
chunk_size = int(math.ceil(len(master_file_list) / NUM_WORKERS))
# Create worker processes
for work_chunk in chunker(master_file_list, chunk_size):
workers.append(IndexWorker(work_chunk, queue))
# Start workers
for worker in workers:
worker.start()
print 'Waiting for workers to complete'
# Loop until all workers are finished
while any([w.is_alive() for w in workers]):
try:
image_obj = queue.get(True, 2)
image_index.append(image_obj)
except Queue.Empty:
print 'Queue was empty'
continue
print 'Workers are complete: {:d} images found'.format(len(image_index))
# Write index as a bzip2'd file to save space
index_file = bz2.BZ2File('images_index.bz2', 'w')
cPickle.dump(image_index, index_file)
index_file.close()
print '\nIndex file images_index.bz2 created. Done.'
if __name__ == '__main__':
sys.exit(main())
software/similar images/find_duplicates_simple.py
#!/opt/local/bin/python2.7
from collections import defaultdict
import imghdr
import os
import sys
import pHash
# Find Duplicates Simple
# Attempt to find images by looking for exact hash collisions.
# This method is not very sophisticated and does not work all
# that well.
def main():
img_map = defaultdict(list)
# Make sure at least one command line argument was provided
if len(sys.argv) < 2:
print 'Usage: find_duplicate_simple <path>'
return -1;
# Print out the path we're walking
path = sys.argv[1]
print 'Step 1: Walk path: {:s}\n'.format(path)
# Walk the root path
for root, dirs, files in os.walk(path):
for file in files:
img_path = os.path.join(root, file)
# Check the make sure the file is an actual image
if not imghdr.what(img_path):
continue
img_hash = pHash.imagehash(img_path)
print '{:s} -> {:016X}'.format(img_path, img_hash)
img_map[img_hash].append(img_path)
print '\n\nStep 2: find duplicates\n'
# Now look through the image hash dictionary for matches
for img_hash, files in img_map.items():
if len(files) > 2:
print '{:016X}'.format(img_hash)
for file_path in files:
print '\t{:s}'.format(file_path)
if __name__ == '__main__':
sys.exit(main())
software/similar images/find_similar.py
#!/opt/local/bin/python2.7
import bz2
from collections import defaultdict
import cPickle
import imghdr
import os
import sys
import pHash
from image import Image
HAMMING_THRESHOLD = 10
CORRELATION_THRESHOLD = 70.0
# Find duplicates by looking over index
# write some description
def find_similar(total_done, index, image):
index_length = len(index)
image_digest = image.make_digest()
# Search the index
ctr = 0
for index_image in index:
ctr += 1
percent_done = int((float(ctr) / index_length) * 100)
sys.stdout.write('\r\tTotal: {:3d}% --- This image: {:3d}%'.format(total_done, percent_done))
sys.stdout.flush()
# Original might be in index, skip it
if image.hash == index_image.hash and image.path == index_image.path:
continue
# Hamming distance hash compare
hamming_distance = pHash.hamming_distance(image.hash, index_image.hash)
# Cross correlation compare
correlation = pHash.crosscorr(image_digest, index_image.make_digest())[1]
# Determine if comparison criteria are within the thresholds
if hamming_distance <= HAMMING_THRESHOLD or \
correlation >= CORRELATION_THRESHOLD:
sys.stdout.write('\r\t--- SIMILAR IMAGE FOUND --- \n')
print '\tHamming distance: {:d}'.format(hamming_distance)
print '\tCross correlation: {:f}'.format(correlation)
print '\tImage path: {:s}\n'.format(index_image.path)
print
def main():
# Make sure at least one command line argument was provided
if len(sys.argv) < 3:
print 'Usage: find_similar.py <image dir root path> <index path>'
return -1;
# Print out the path we're walking
root_path = sys.argv[1]
index_path = sys.argv[2]
# Load image index
index_file = bz2.BZ2File(index_path, 'r')
image_index = cPickle.load(index_file)
index_file.close()
print 'Looking for similar images from from path: {:s}'.format(root_path)
# Walk the root path and count all images
# (is there a better way to do this?)
image_counter = 0
for root, dirs, files in os.walk(root_path):
for file in files:
image_path = os.path.join(root, file)
# Check the make sure the file is a JPEG
if not imghdr.what(image_path) == 'jpeg':
continue
image_counter += 1
print 'Done counting, {:d} images total.'.format(image_counter)
# Walk the root path
ctr = 0
for root, dirs, files in os.walk(root_path):
for file in files:
image_path = os.path.join(root, file)
# Check the make sure the file is a JPEG
if not imghdr.what(image_path) == 'jpeg':
continue
ctr += 1
percent_done = int((float(ctr) / image_counter) * 100)
print '\n\nLooking for similar -- {:s}'.format(image_path)
image_obj = Image(image_path)
# Find similar images by searching the index
find_similar(percent_done, image_index, image_obj)
print '\nDone.'
if __name__ == '__main__':
sys.exit(main())
software/similar images/image.py
import copy
import pHash
class Image(object):
def __init__(self, path, hash=None, coefficients=None):
self.path = path
if not hash:
self.hash = pHash.imagehash(self.path)
else:
self.hash = hash
if not coefficients:
self.coefficients = copy.copy(pHash.image_digest(self.path, 1.0, 1.0, 180).coeffs)
else:
self.coefficients = coefficients
def make_digest(self):
digest = pHash.Digest()
digest.coeffs = copy.copy(self.coefficients)
digest.size = len(self.coefficients)
return digest
def __repr__(self):
print 'Image: {:s}'.format(self.path)
print '\tHash: {:016X}'.format(self.hash)
print '\tDigest coefficients: {:s}'.format(str(self.coefficients))
software/similar images/test.py
import sys
import pHash
def main():
hash1 = pHash.imagehash(sys.argv[1])
hash2 = pHash.imagehash(sys.argv[2])
print 'Image 1: {:X}'.format(hash1)
print 'Image 2: {:X}'.format(hash2)
print 'Distance {:d}'.format(pHash.hamming_distance(hash2, hash1))
if __name__ == '__main__':
sys.exit(main())

Also available in: Unified diff