#! /usr/bin/env python # smoke-rng.py - smoke detector RNG proof of concept utility # # Adam Laurie # http://www.aperturelabs.com # # This code is copyright (c) Aperture Labs Ltd., 2011, All rights reserved. # import opencv import hashlib from opencv import highgui import time import sys if len(sys.argv) > 1: camera= int(sys.argv[1]) else: camera= 0 highgui.cvNamedWindow("old smokey", 1) capture = highgui.cvCreateCameraCapture(camera) width = None #leave None for auto-detection height = None #leave None for auto-detection if width is None: width = int(highgui.cvGetCaptureProperty(capture, highgui.CV_CAP_PROP_FRAME_WIDTH)) else: highgui.cvSetCaptureProperty(capture,highgui.CV_CAP_PROP_FRAME_WIDTH,width) if height is None: height = int(highgui.cvGetCaptureProperty(capture, highgui.CV_CAP_PROP_FRAME_HEIGHT)) else: highgui.cvSetCaptureProperty(capture,highgui.CV_CAP_PROP_FRAME_HEIGHT,height) print 'Image is %dx%d' % (width, height) print 'Brightness:', highgui.cvGetCaptureProperty(capture,highgui.CV_CAP_PROP_BRIGHTNESS) print 'Contrast:', highgui.cvGetCaptureProperty(capture,highgui.CV_CAP_PROP_CONTRAST) print 'Saturation:', highgui.cvGetCaptureProperty(capture,highgui.CV_CAP_PROP_SATURATION) print 'Hue:', highgui.cvGetCaptureProperty(capture,highgui.CV_CAP_PROP_HUE) # flags accumulate= False accumulate_xor= False calibrate= False calibrate_frames= 10 display_grid= False gridsize= 4 mask= False hash_md5= False hash_sha1= False hash_sha224= False hash_sha256= False hash_sha384= False hash_sha512= False random= False threshold= False zeros= 0 # counters bits= 0 frames= 0 threshold_min= 0xf0 calibrate_count= 0 # buffers img = highgui.cvQueryFrame(capture) full_mask= opencv.cvCreateImage(opencv.cvGetSize(img), opencv.IPL_DEPTH_8U, 1) opencv.cvFloodFill(full_mask, (0,0), opencv.CV_RGB(0xff,0xff,0xff)) filter_mask= opencv.cvCreateImage(opencv.cvGetSize(img), opencv.IPL_DEPTH_8U, 1) previous = opencv.cvCreateImage(opencv.cvGetSize(img), opencv.IPL_DEPTH_8U, 1) target = opencv.cvCreateImage(opencv.cvGetSize(img), opencv.IPL_DEPTH_8U, 1) accumulated = opencv.cvCreateImage(opencv.cvGetSize(img), opencv.IPL_DEPTH_8U, 1) display = opencv.cvCreateImage(opencv.cvGetSize(img), opencv.IPL_DEPTH_8U, 1) grid = opencv.cvCreateImage(opencv.cvGetSize(img), opencv.IPL_DEPTH_8U, 1) print opencv.cvGetSize(img) # draw grid def draw_grid(): global grid global gridsize global width global height opencv.cvSet(grid, opencv.cvScalar(0,0,0)) # draw verticals working_width= width/gridsize*gridsize working_height= height/gridsize*gridsize for x in range(1,gridsize + 1): opencv.cvLine(grid, (x*(working_width / gridsize), 0), (x*(working_width / gridsize), working_height), opencv.cvScalar(0xff,0xff,0xff),1) # draw horizontals for y in range(1,gridsize + 1): opencv.cvLine(grid, (0, y*(working_height / gridsize)), (working_width, y*(working_height / gridsize)), opencv.cvScalar(0xff,0xff,0xff),1) draw_grid() # main loop while True: # image processing del img img = highgui.cvQueryFrame(capture) # we're only interested in black & white opencv.cvCvtColor(img, target, opencv.CV_BGR2GRAY) if threshold: opencv.cvThreshold( target, target, threshold_min, 0xff, opencv.CV_THRESH_BINARY ); if mask: # XOR to create mask of bits not used last time opencv.cvXor(previous, full_mask, filter_mask) # now AND with mask to get fresh bits opencv.cvAnd(target, filter_mask, target) if accumulate: opencv.cvOr(target, accumulated, accumulated) target= opencv.cvCloneImage(accumulated) if accumulate_xor: opencv.cvXor(target, accumulated, accumulated) target= opencv.cvCloneImage(accumulated) if display_grid: opencv.cvOr(target, grid, display) highgui.cvShowImage("old smokey", display) else: highgui.cvShowImage("old smokey", target) del previous previous= opencv.cvCloneImage(target) # post display processing if hash_sha1: print 'sha1: ', hashlib.sha1(target.imageData).hexdigest() if hash_sha224: print 'sha224:', hashlib.sha224(target.imageData).hexdigest() if hash_sha256: print 'sha256:', hashlib.sha256(target.imageData).hexdigest() if hash_sha512: print 'sha512:', hashlib.sha512(target.imageData).hexdigest() if hash_md5: print 'md5: ', hashlib.md5(target.imageData).hexdigest() if random or calibrate: # divide image into grid and count non-zero dots in each element # overall size will be cropped to an exact multiple of grid elements out= '' working_width= width/gridsize*gridsize working_height= height/gridsize*gridsize for x in range(0,working_width,working_width/gridsize): for y in range(0,working_height,working_height/gridsize): count= 0 for xx in range(x, x + width/gridsize): for yy in range(y, y + height/gridsize): # last grid square may not exactly fit! if xx >= width or yy >= height: continue if opencv.cvGetReal2D(target, yy, xx) != 0: count += 1 if not calibrate: print '%05d' % count, if not zeros or count > 10: out += '%d' % (count % 2) if not calibrate: print out, '%04X' % int(out,2) bits += len(out) frames += 1 if calibrate: calibrate_count += 1 if calibrate_count == calibrate_frames: print 'gridsize %dx%d: %d bits in %d frames, average %f bits per frame (max %d)' % (gridsize, gridsize, bits, frames, float(bits) / float(frames), gridsize*gridsize) gridsize += 1 draw_grid() frames= 0 bits= 0 calibrate_count= 0 # keystroke processing k = highgui.cvWaitKey(10) if k == '1': hash_sha1= not hash_sha1 print 'hash_sha1', hash_sha1 if k == '2': hash_sha224= not hash_sha224 print 'hash_sha224', hash_sha224 if k == '5': hash_md5= not hash_md5 print 'hash_md5', hash_md5 if k == '6': hash_sha256= not hash_sha256 print 'hash_sha256', hash_sha256 if k == '7': hash_sha512= not hash_sha512 print 'hash_sha512', hash_sha512 if k == 'a': accumulate= not accumulate print 'accumulate images', accumulate if k == 'A': opencv.cvSet(accumulated, opencv.cvScalar(0,0,0)) print 'accumulated images cleared' if k == 'b': count= 0 for x in range(width): for y in range(height): #print '06x' % opencv.cvmGet(img, x, y), if opencv.cvGetReal2D(target, y, x) != 0.0: print '%d-%d:' % (x,y), opencv.cvGetReal2D(target, y, x), count += 1 print '%d hits' % count if k == 'c': calibrate= not calibrate print 'calibrate', calibrate if k == 'd': display_grid= not display_grid if k == 'g': if gridsize >= 3: gridsize -= 1 draw_grid() print 'gridsize', gridsize if k == 'G': gridsize += 1 draw_grid() print 'gridsize', gridsize if k == 'h': print '1 : generate sha1 hash' print '2 : generate sha224 hash' print '5 : generate md5 hash' print '6 : generate sha256 hash' print '7 : generate sha512 hash' print 'a : accumulate images' print 'A : reset accumulated images' print 'b : show binary stats' print 'c : perform auto gridsize calibration tests' print 'd : display grid' print 'g : decrease gridsize' print 'G : increase gridsize' print 'h : print help' print 'm : apply mask filter' print 'p : pause' print 'r : generate random numbers' print 's : print stats' print 'S : reset stats' print 't : apply threshold filter' print '+ : increase threshold filter minimum' print '- : decrease threshold filter minimum' print 'x : xor accumulate images' print 'z : ignore zero grids' if k == 'm': mask= not mask print 'mask filter', mask if k == 'p': print 'paused' highgui.cvWaitKey(0) if k == 'r': random= not random if k == 's': print '%d bits in %d frames, average %f bits per frame (max %d)' % (bits, frames, float(bits) / float(frames), gridsize*gridsize) if k == 'S': bits= 0 frames= 0 print 'stats reset' if k == 't': threshold= not threshold print 'threshold filter', threshold if k == '-': if threshold_min >= 2: threshold_min -= 1 print 'threshold filter %02x' % threshold_min if k == '+': threshold_min += 1 print 'threshold filter %02x' % threshold_min if k == 'q': print '%d bits in %d frames, average %f bits per frame (max %d)' % (bits, frames, float(bits) / float(frames), gridsize*gridsize) break if k == 'x': accumulate_xor= not accumulate_xor print 'accumulate_xor images', accumulate_xor if k == 'z': zeros= not zeros print 'ignore zero grids', zeros