Exemple #1
0
    def __init__(self, node_name):
        self.node_name = node_name
        self.resize_window_height = 0
        self.resize_window_width = 0

        rospy.init_node(node_name)
        rospy.loginfo("Starting node " + str(node_name))

        rospy.on_shutdown(self.cleanup)

        # Initialize a number of global variables
        self.frame = None
        self.display_image = None

        self.cv_image_pub = rospy.Publisher('/cv_image', Image)

        self.cv_window_name = self.node_name
        cv.NamedWindow(self.cv_window_name, cv.CV_WINDOW_NORMAL)
        if self.resize_window_height > 0 and self.resize_window_width > 0:
            cv.ResizeWindow(self.cv_window_name, self.resize_window_width,
                            self.resize_window_height)
        else:
            cv.ResizeWindow(self.cv_window_name, 640, 480)

        # Create the cv_bridge object
        self.bridge = CvBridge()
        self.image_sub = rospy.Subscriber("/camera/rgb/image_raw", Image,
                                          self.image_callback)
Exemple #2
0
    def __init__(self, node_name):
        super(MotionDetection, self).__init__(node_name)

        self.node_name = node_name

        # Three three frames to compare
        self.frame_minus = None
        self.frame_now = None
        self.frame_plus = None

        self.erode_kernel = cv2.getStructuringElement(cv2.MORPH_ERODE, (3, 3))
        self.dilate_kernel = cv2.getStructuringElement(cv2.MORPH_DILATE,
                                                       (3, 3))

        self.window_name = "Motion Detection"
        cv.NamedWindow(self.window_name, cv.CV_WINDOW_NORMAL)
        cv.ResizeWindow(self.window_name, 640, 480)
Exemple #3
0
    def __init__(self, node_name):
        super(MotionHistory, self).__init__(node_name)

        self.node_name = node_name

        self.visuals = [
            'input', 'frame_diff', 'motion_hist', 'motion_hist_color',
            'grad_orient'
        ]
        #cv2.namedWindow('motion_templates')
        cv2.createTrackbar('visual', node_name, 2,
                           len(self.visuals) - 1, nothing)
        cv2.createTrackbar('threshold', node_name, DEFAULT_THRESHOLD, 255,
                           nothing)
        self.motion_history = None

        cv.NamedWindow("Contours", cv.CV_WINDOW_NORMAL)
        cv.ResizeWindow("Contours", 640, 480)
Exemple #4
0
    def __init__(self, node_name):
        super(MotionDetection, self).__init__(node_name)

        self.node_name = node_name

        self.prev_frame = None
        self.ave_diff = None

        self.erode_kernel = cv2.getStructuringElement(cv2.MORPH_ERODE, (3, 3))
        self.dilate_kernel = cv2.getStructuringElement(cv2.MORPH_DILATE,
                                                       (3, 3))

        self.window_name = "Motion Detection"
        cv.NamedWindow(self.window_name, cv.CV_WINDOW_NORMAL)
        cv.ResizeWindow(self.window_name, 640, 480)

        self.kernel_size = 3
        self.scale = 1
        self.delta = 0
        self.ddepth = cv2.CV_16S
Exemple #5
0
            sys.exit(1)
    cap = cap_camera(int(args.cam))
elif args.file:
    cap = cap_file(args.file)
else:
    raise ValueError("Must specify either --cam or --file!")

detector_state = DetectorState((640, 480), 128, 5, approx_object_size=15.0)

d = OrderedDict([('h_low', 0), ('h_high', 255), ('s_low', 0), ('s_high', 255),
                 ('v_low', 0), ('v_high', 255)])
white_sample = threshold.Threshold("white_sample", d)

cv.NamedWindow("image", flags=cv.CV_WINDOW_NORMAL)
cv.MoveWindow("image", 20, 20)
cv.ResizeWindow("image", 700, 700)

cv.NamedWindow("original", flags=cv.CV_WINDOW_NORMAL)
cv.MoveWindow("original", 650, 20)
cv.ResizeWindow("original", 640, 480)

cv.NamedWindow("heuristics", flags=cv.CV_WINDOW_NORMAL)
cv.MoveWindow("heuristics", 400, 400)
cv.ResizeWindow("heuristics", 640, 480)

heuristics = HeuristicStack({
    (PhysicalSizeHeuristic(debug=False), 1.0),
    #(LargestHeuristic(debug=False), 0.5),
    (NormalBlobSizeHeuristic(debug=False), 0.5),
    (DensityHeuristic2(debug=False), 0.5)
})
Exemple #6
0
    def __init__(self, node_name):
        self.node_name = node_name

        rospy.init_node(node_name)
        rospy.loginfo("Starting node " + str(node_name))

        rospy.on_shutdown(self.cleanup)

        # A number of parameters to determine what gets displayed on the
        # screen. These can be overridden the appropriate launch file
        self.show_text = rospy.get_param("~show_text", True)
        self.show_features = rospy.get_param("~show_features", True)
        self.show_boxes = rospy.get_param("~show_boxes", True)
        self.flip_image = rospy.get_param("~flip_image", False)
        self.feature_size = rospy.get_param("~feature_size", 1)

        # Initialize the Region of Interest and its publisher
        self.ROI = RegionOfInterest()
        self.roi_pub = rospy.Publisher("/roi", RegionOfInterest, queue_size=1)

        # Initialize a number of global variables
        self.frame = None
        self.frame_size = None
        self.frame_width = None
        self.frame_height = None
        self.depth_image = None
        self.marker_image = None
        self.display_image = None
        self.grey = None
        self.prev_grey = None
        self.selected_point = None
        self.selection = None
        self.drag_start = None
        self.keystroke = None
        self.detect_box = None
        self.track_box = None
        self.display_box = None
        self.keep_marker_history = False
        self.night_mode = False
        self.auto_face_tracking = False
        self.cps = 0  # Cycles per second = number of processing loops per second.
        self.cps_values = list()
        self.cps_n_values = 20
        self.busy = False
        self.resize_window_width = 0
        self.resize_window_height = 0
        self.face_tracking = False

        # Create the main display window
        self.cv_window_name = self.node_name
        cv.NamedWindow(self.cv_window_name, cv.CV_WINDOW_NORMAL)
        if self.resize_window_height > 0 and self.resize_window_width > 0:
            cv.ResizeWindow(self.cv_window_name, self.resize_window_width,
                            self.resize_window_height)

        # Create the cv_bridge object
        self.bridge = CvBridge()

        # Set a call back on mouse clicks on the image window
        cv.SetMouseCallback(self.node_name, self.on_mouse_click, None)

        # Subscribe to the image and depth topics and set the appropriate callbacks
        # The image topic names can be remapped in the appropriate launch file
        self.image_sub = rospy.Subscriber("input_rgb_image",
                                          Image,
                                          self.image_callback,
                                          queue_size=1)
        self.depth_sub = rospy.Subscriber("input_depth_image",
                                          Image,
                                          self.depth_callback,
                                          queue_size=1)
    def __init__(self, node_name):
        self.node_name = node_name

        rospy.init_node(node_name)

        rospy.loginfo("Starting node " + str(node_name))

        rospy.on_shutdown(self.cleanup)

        # A number of parameters to determine what gets displayed on the
        # screen. These can be overridden the appropriate launch file
        self.show_text = rospy.get_param("~show_text", True)

        # Initialize a number of global variables
        self.frame = None
        self.frame_size = None
        self.frame_width = None
        self.frame_height = None
        self.flip_image = False
        self.mask = None
        self.marker_image = None
        self.display_image = None
        self.keystroke = None
        self.cps = 0  # Cycles per second = number of processing loops per second.
        self.cps_values = list()
        self.cps_n_values = 20
        self.resize_window_width = 0
        self.resize_window_height = 0
        self.image_count = 0

        # Initialize output folder path to current terminal directory
        self.output_folder = os.path.dirname(
            os.path.realpath('__file__')
        )[:-8] + "/include/opencv_camera_calibration/camera_cal_data"

        # Initialize findChessboardCorners and drawChessboardCorners parameters
        self.patternSize_columns = rospy.get_param("~patternSize_columns", 10)
        self.patternSize_rows = rospy.get_param("~patternSize_rows", 8)

        # Initialize cornerSubPix parameters
        self.winSize_columns = rospy.get_param("~winSize_columns", 5)
        self.winSize_rows = rospy.get_param("~winSize_rows", 5)
        self.criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER,
                         30, 0.001)

        # Create the main display window
        self.cv_window_name = self.node_name
        cv.NamedWindow(self.cv_window_name, cv.CV_WINDOW_NORMAL)
        if self.resize_window_height > 0 and self.resize_window_width > 0:
            cv.ResizeWindow(self.cv_window_name, self.resize_window_width,
                            self.resize_window_height)

        # Create the cv_bridge object
        self.bridge = CvBridge()

        # Subscribe to the image topic and set the appropriate callback
        # The image topic name can be remapped in the appropriate launch file
        self.image_sub = rospy.Subscriber("input_rgb_image",
                                          Image,
                                          self.image_callback,
                                          queue_size=5)

        # Create an image publisher to output the display_image
        self.image_pub = rospy.Publisher("output_rgb_image",
                                         Image,
                                         queue_size=5)
    def _process_movie(self, **kwargs):
        """
			Function for analyzing a full film or video. This is where the magic happens when we're making analyses. Function will exit if neither a movie path nor a data path are supplied. This function is not intended to be called directly. Normally, call one of the two analyze_ functions instead, which will call this function.
		
		"""

        ap = self._check_pcorr_params(kwargs)
        verbose = ap['verbose']

        if not HAVE_CV:
            print "WARNING: You must install OpenCV in order to analyze or view!"
            return

        if (self.movie_path is None) and (self.data_path is
                                          None) and ap['mode'] is 'analysis':
            print "ERROR: Must supply both a movie and a data path for analysis!"
            return

        have_mov = os.path.exists(self.movie_path)
        have_data = os.path.exists(self.data_path)

        if (have_mov is False) and (have_data is False):
            print "Both movie file and data file are missing! Please supply at least one."
            return None

        print ap

        if have_mov:
            self.capture = cv2.VideoCapture(self.movie_path)
            frame_width = int(self.capture.get(cv.CV_CAP_PROP_FRAME_WIDTH))
            frame_height = int(self.capture.get(cv.CV_CAP_PROP_FRAME_HEIGHT))
        else:
            frame_width = 640
            frame_height = int(frame_width / self._read_json_value('aspect'))

        fps = ap['fps']
        grid_x_divs = ap['grid_divs_x']
        grid_y_divs = ap['grid_divs_y']
        frame_size = (frame_width, frame_height)
        grid_width = int(frame_width / grid_x_divs)
        grid_height = int(frame_height / grid_y_divs)
        grid_size = (grid_width, grid_height)

        centers_x = range((frame_width / 16), frame_width, (frame_width / 8))
        centers_y = range((frame_height / 16), frame_height,
                          (frame_height / 8))

        if verbose:
            print fps, ' | ', frame_size, ' | ', grid_size

        # container for prev. frame's grayscale subframes
        prev_sub_grays = []

        if ap['offset'] > 0:
            offset_secs = ap['offset']
        else:
            offset_secs = 0

        print "%%% ", ap['duration']

        if ap['duration'] > 0:
            dur_secs = ap['duration']
        elif ap['duration'] < 0:
            ap['duration'] = self.determine_movie_length()
        else:
            print "Duration cannot be 0."
            return
        dur_secs = ap['duration']

        stride_frames = ap['stride']
        stride_hop = stride_frames - 1

        print "1. ", ap['duration']
        print "2. ", dur_secs

        # check offset first, then compress duration, if needed
        offset_secs = min(max(offset_secs, 0), ap['duration'])
        dur_secs = min(max(dur_secs, 0), (ap['duration'] - offset_secs))
        offset_strides = int(offset_secs * (fps / stride_frames))
        dur_strides = int(dur_secs * (fps / stride_frames))
        offset_frames = offset_strides * stride_frames
        dur_frames = dur_strides * stride_frames

        if verbose:
            print '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'
            print 'DUR TOTAL: ', dur_total_secs
            print "OFFSET (SECONDS): ", offset_secs
            print "OFFSET (STRIDES): ", offset_strides
            print "OFFSET (FRAMES): ", offset_frames
            print "DUR (SECONDS): ", dur_secs
            print 'DUR (STRIDES): ', dur_strides
            print 'DUR (FRAMES): ', dur_frames
            print 'XDIVS: ', grid_x_divs
            print 'YDIVS: ', grid_y_divs
            print "FPS: ", fps
            print "stride_frames: ", stride_frames

        # set up memmap
        if ap['mode'] == 'playback' and ap['display'] == True:
            fp = np.memmap(self.data_path,
                           dtype='float32',
                           mode='r',
                           shape=((offset_strides + dur_strides), (64 + 1), 2))
        else:
            fp = np.memmap(self.data_path,
                           dtype='float32',
                           mode='w+',
                           shape=(dur_strides, (64 + 1), 2))

        if ap['display']:
            cv.NamedWindow('Image', cv.CV_WINDOW_AUTOSIZE)
            cv.ResizeWindow('Image', frame_width, frame_height)

        self.frame_idx = offset_frames
        end_frame = offset_frames + dur_frames

        if have_mov:
            self.capture.set(cv.CV_CAP_PROP_POS_FRAMES, offset_frames)
            ret, frame = self.capture.read()
            if frame is None:
                print 'Frame error! Exiting...'
                return  # no image captured... end the processing
            frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            prev_frame_gray = np.float32(frame_gray[:])

            fhann = cv2.createHanningWindow((frame_width, frame_height),
                                            cv2.CV_32FC1)
            ghann = cv2.createHanningWindow((grid_width, grid_height),
                                            cv2.CV_32FC1)

            for row in range(grid_y_divs):
                for col in range(grid_x_divs):
                    prev_sub_grays += [
                        np.float32(frame_gray[(row *
                                               grid_height):((row + 1) *
                                                             grid_height),
                                              (col * grid_width):((col + 1) *
                                                                  grid_width)])
                    ]

        else:
            frame = np.empty((frame_width, frame_height), np.uint8)
            print frame.shape

        self.frame_idx += 1

        print "<<< ", frame.mean()
        # 		cv.ShowImage('Image', cv.fromarray(frame))

        while self.frame_idx < end_frame:

            if (self.frame_idx % 1000) == 0:
                print 'fr. idx: ', self.frame_idx, ' (', self.frame_idx / float(
                    end_frame), ' | ', end_frame, ')'

            if have_mov:
                # grab next frame
                ret, frame = self.capture.read()
                if frame is None:
                    print 'Frame error! Exiting...'
                    break  # no image captured... end the processing
                frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            else:
                frame[:] = 0

            # display stage (full)
            if ap['mode'] == 'playback' and ap['display']:
                fret = fp[self.frame_idx][64]
                # print fret
            elif have_mov:
                fret, fres = cv2.phaseCorrelateRes(prev_frame_gray,
                                                   np.float32(frame_gray[:]),
                                                   fhann)
                print fret
                if abs(fres) > 0.01:
                    fp[self.frame_idx][64] = [(fret[0] / frame_width),
                                              (fret[1] / frame_height)]
                else:
                    fp[self.frame_idx][64] = [0, 0]
            else:
                return

            # display stage (gridded)
            for row in range(grid_y_divs):
                for col in range(grid_x_divs):
                    if ap['mode'] == 'playback' and ap['display']:
                        cell = ((row * 8) + col)
                        gret = fp[self.frame_idx][cell]
                    elif have_mov:
                        sub_gray = np.float32(
                            frame_gray[(row * grid_height):((row + 1) *
                                                            grid_height),
                                       (col * grid_width):((col + 1) *
                                                           grid_width)][:])
                        gret, gres = cv2.phaseCorrelateRes(
                            prev_sub_grays[(row * grid_x_divs) + col],
                            sub_gray, ghann)
                        prev_sub_grays[(row * grid_x_divs) + col] = sub_gray
                        if abs(gres) > 0.7:  # WAS 0.01!!!!
                            fp[self.frame_idx][(row * grid_x_divs) + col] = [
                                (gret[0] / grid_width), (gret[1] / grid_height)
                            ]
                        else:
                            fp[self.frame_idx][(row * grid_x_divs) +
                                               col] = [0, 0]
                    else:
                        return

                    if ap['display'] and (gret[0] != 0 and gret[1] != 0):
                        print gret
                        print grid_size
                        print centers_x[col]
                        print centers_y[row]
                        xval = int(
                            min((gret[0] * 1000), grid_size[0]) +
                            centers_x[col])
                        yval = int(
                            min((gret[1] * 1000), grid_size[1]) +
                            centers_y[row])
                        # print ((centers_x[i], centers_y[j], xval, yval), False, (0,255,255))
                        print(centers_x[col], centers_y[row])
                        print(xval, yval)
                        cv2.line(frame, (centers_x[col], centers_y[row]),
                                 (xval, yval), (255, 255, 255))

            #### SHOW
            if ap['display'] and have_mov:
                print "<<< ", frame.mean()
                cv.ShowImage('Image', cv.fromarray(frame))
            fp.flush()

            self.frame_idx += 1
            if have_mov:
                self.prev_gray = np.float32(frame_gray[:])

            # handle events for abort
            k = cv.WaitKey(int(1000 / ap['afps']))
            if k % 0x100 == 27:
                # user has press the ESC key, so exit
                break

        del fp
        if ap['display']:
            cv2.destroyAllWindows()
Exemple #9
0
# -*- coding: utf-8 -*-
##转载请注明:@小五义http://www.cnblogs.com/xiaowuyi  QQ群:64770604
import cv2.cv as cv  
import cv2  
from cv2 import VideoCapture  
      
#cv.NamedWindow("W1", cv.CV_WINDOW_AUTOSIZE)  
cv.NamedWindow("W1",cv.CV_WINDOW_NORMAL)

cv.ResizeWindow("W1", 600, 600)
      
    #找到设备对象  
capture = cv.CaptureFromCAM(0) 

      
    #检测人脸函数  
      
def repeat():  
      
        #每次从摄像头获取一张图片  
    frame = cv.QueryFrame(capture)

    image_size = cv.GetSize(frame)#获取图片的大小  
    #print image_size
          
    greyscale = cv.CreateImage(image_size, 8, 1)#建立一个相同大小的灰度图像

    cv.CvtColor(frame, greyscale, cv.CV_BGR2GRAY)#将获取的彩色图像,转换成灰度图像

    storage = cv.CreateMemStorage(0)#创建一个内存空间,人脸检测是要利用,具体作用不清楚
          
import cv2.cv as cv

# Load images
image = cv.LoadImage('../pic/QQ20171118-0.jpg',
                     cv.CV_LOAD_IMAGE_COLOR)  # Load the image
# Or just: image = cv.LoadImage('/Users/heyu/Pictures/picture/IMG_1438.JPG')

cv.NamedWindow('a_window', cv.CV_WINDOW_AUTOSIZE)  # Facultative
cv.ResizeWindow('a_window', 640, 480)
cv.ShowImage('a_window', image)  # show the image

# cv.SaveImage("thumb.png", thumb)
cv.WaitKey(0)  # Wait for user input and quit
	def _process_movie(self, **kwargs):
		"""
		Function for analyzing a full film or video. This is where the magic happens when we're making pixel-histogram analyses. Function will exit if neither a movie path nor a data path are supplied. This function is not intended to be called directly. Normally, call one of the two analyze_ functions instead, which will call this function.
		
		"""
		if not HAVE_CV:
			return
		
		if (self.movie_path is None) or (self.data_path is None):
			print "Must supply both a movie and a data path!"
			return
		
		ap = self._check_cflab_params(kwargs)
		verbose = ap['verbose']
		
		print ap
		# ap = self.analysis_params
				
		self.capture = cv2.VideoCapture(self.movie_path)
		
		self._write_metadata_to_json()
		# probably should generate and check for errors
		
		fps = ap['fps']
		grid_x_divs = ap['grid_divs_x']
		grid_y_divs = ap['grid_divs_y']
		frame_width = int(self.capture.get(cv.CV_CAP_PROP_FRAME_WIDTH))
		frame_height = int(self.capture.get(cv.CV_CAP_PROP_FRAME_HEIGHT))
		frame_size = (frame_width, frame_height)
		hist_width = int(frame_width * ap['hist_width_ratio'])
		hist_height = int(frame_height * ap['hist_height_ratio'])
		hist_size = (hist_width, hist_height)
		grid_width = int(hist_width/grid_x_divs)
		grid_height = int(hist_height/grid_y_divs)
		grid_size = (grid_width, grid_height)

		
		if verbose:
			print ap['lrange'][0], ' | ', ap['arange'][0], ' | ', ap['brange'][0], ' | ', ap['lrange'][1], ' | ', ap['arange'][1], ' | ', ap['brange'][1]
			print fps, ' | ', hist_size, ' | ', grid_size
		
		grid_l_star = np.zeros((16,1), dtype=np.float32)
		grid_a_star = np.zeros((16,1), dtype=np.float32)
		grid_b_star = np.zeros((16,1), dtype=np.float32)
		
		grid_mask = np.zeros(grid_size, dtype=np.float32)
		grid_lab = np.zeros((grid_size[0], grid_size[1], 3), dtype=np.float32)
	
		l_star = np.zeros((16,1), dtype=np.float32)
		a_star = np.zeros((16,1), dtype=np.float32)
		b_star = np.zeros((16,1), dtype=np.float32)
		
		mask = np.zeros((frame_size[0], frame_size[1], 3), dtype=np.float32)
		lab = np.zeros((frame_size[0], frame_size[1], 3), dtype=np.float32)

		dims = ap['ldims']
		
		lab_min = (ap['lrange'][0], ap['arange'][0], ap['brange'][0])
		lab_max = (ap['lrange'][1], ap['arange'][1], ap['brange'][1])
		bin_w = int((hist_width * ap['hist_width_ratio']) / (ap['ldims'] * grid_x_divs))
		third_bin_w = int(bin_w/3)
	
		l_histo = np.arange(ap['lrange'][0], ap['lrange'][1], ap['ldims']).reshape((ap['ldims'],1))
		a_histo = np.arange(ap['arange'][0], ap['arange'][1], ap['adims']).reshape((ap['adims'],1))
		b_histo = np.arange(ap['brange'][0], ap['brange'][1], ap['bdims']).reshape((ap['bdims'],1))
		
		if ap['verbose']: print third_bin_w
				
		histimg = np.zeros((int(hist_height*1.25), int(hist_width), 3), np.uint8)
		
		# get total_frame_count and set up the memmapped file

		if ap['offset'] > 0:
			offset_secs = ap['offset']
		else:
			offset_secs = 0
		
		print ap['duration']
		
		if ap['duration'] > 0:
			dur_secs = ap['duration']
		elif ap['duration'] < 0:
			ap['duration'] = self.determine_movie_length()
		else:
			print "Duration cannot be 0."
			return
		dur_secs = ap['duration']
		
		stride_frames = ap['stride']
		stride_hop = stride_frames - 1

		print ap['duration']
		print dur_secs
		
		# check offset first, then compress duration, if needed
		offset_secs = min(max(offset_secs, 0), ap['duration'])
		dur_secs = min(max(dur_secs, 0), (ap['duration'] - offset_secs))
		offset_strides = int(offset_secs * (fps / stride_frames))
		dur_strides = int(dur_secs * (fps / stride_frames))
		offset_frames = offset_strides * stride_frames
		dur_frames = dur_strides * stride_frames
		
		if verbose:
			print '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'
			print 'FRAMES: ', int(self.capture.get(cv.CV_CAP_PROP_FRAME_COUNT))
			print 'DUR TOTAL: ', ap['duration']
			print "OFFSET (SECONDS): ", offset_secs
			print "OFFSET (STRIDES): ", offset_strides
			print "OFFSET (FRAMES): ", offset_frames
			print "DUR (SECONDS): ", dur_secs
			print 'DUR (STRIDES): ', dur_strides
			print 'DUR (FRAMES): ', dur_frames
			print "FPS: ", fps
			print "stride_frames: ", stride_frames
		
		# set up memmap
		if ap['mode'] == 'playback' and ap['display'] == True:
			 fp = np.memmap(self.data_path, dtype='float32', mode='r', shape=((offset_strides + dur_strides),(ap['grid_divs_x']*ap['grid_divs_y'])+1,3,ap['ldims']))
		else:
			fp = np.memmap(self.data_path, dtype='float32', mode='w+', shape=(dur_strides, (ap['grid_divs_x']*ap['grid_divs_x'])+1,3,ap['ldims']))
		
		# set some drawing constants
		vert_offset = int(frame_height*ap['hist_vert_offset_ratio'])
		grid_height_ratio = grid_height/255.

		#timing state vars
		self.frame_idx = offset_frames
		end_frame = offset_frames + dur_frames
		
		if ap['display']:
			cv.NamedWindow('Image', cv.CV_WINDOW_AUTOSIZE)
			cv.NamedWindow('Histogram', hist_width)
			cv.ResizeWindow('Histogram', int(hist_width*ap['hist_width_ratio']*1.0), int(hist_height*ap['hist_height_ratio']*1.25))
			cv.MoveWindow('Histogram', int(frame_width*ap['hist_horiz_offset_ratio']), vert_offset)
			
			# should probably assert that ldims == adims == bdims, but hey we trust people
			lcolors, acolors, bcolors= range(ap['ldims']), range(ap['adims']), range(ap['bdims'])
			for d in range (dims):
				gray_val = (d * 192. / dims) + 32
				lcolors[d] = cv.Scalar(255., gray_val, gray_val)
				acolors[d] = cv.Scalar(gray_val, 128., 128.)
				bcolors[d] = cv.Scalar(gray_val, gray_val, gray_val)
			six_points = self.build_bars(grid_width, grid_height, bin_w, third_bin_w, grid_x_divs, grid_y_divs, 16) # 16: number of bins
			self.capture.set(cv.CV_CAP_PROP_POS_FRAMES, offset_frames)

		while self.frame_idx < end_frame:
			
			if verbose:
				print('fr. idx: %6i || %.4f (/%i) [ %i | %i ]' % (self.frame_idx, ((self.frame_idx - offset_frames) / float(dur_frames)), dur_frames, offset_frames, end_frame))

			if (self.frame_idx%stride_frames) == 0:

				# frame grab
				ret, frame = self.capture.read()
				curr_stride_frame = self.frame_idx/stride_frames
				# reality check
				if frame is None: 
					print 'Frame error! Exiting...'
					break # no image captured... end the processing
				
				# access stage (full)
				if ap['mode'] == 'playback':
					lbins, abins, bbins = fp[curr_stride_frame][0][0], fp[curr_stride_frame][0][1], fp[curr_stride_frame][0][2]
					# if verbose: print (np.sum(lbins), np.sum(abins), np.sum(bbins))
				else:
					lbins, abins, bbins = self._analyze_image(frame, fp, curr_stride_frame, lab, lab_min, lab_max, l_star, a_star, b_star, mask, l_histo, a_histo, b_histo, 0, 0, 0, 1., thresh=ap['threshold'])

				# display stage (full)
				if ap['display']:
					histimg[:] = 0
					for d in range(dims):
						# for all the bins, get the value, and scale to the size of the grid
						lval, aval, bval = int(lbins[d]*255.), int(abins[d]*255.), int(bbins[d]*255.)
						#draw the rectangle in the wanted color
						self.make_rectangles(cv.fromarray(histimg), six_points, 6, 0, 0, d, [lval, aval, bval], grid_height_ratio, [lcolors, acolors, bcolors], voffset=hist_height)
				
				# access stage (gridded)
				for i in range(grid_x_divs):
					for j in range(grid_y_divs):
						if ap['mode'] == 'playback':
							lbins, abins, bbins = fp[(curr_stride_frame)][(j*grid_x_divs)+i+1][0], fp[curr_stride_frame][(j*grid_x_divs)+i+1][1], fp[curr_stride_frame][(j*grid_x_divs)+i+1][2]
						else:
							sub = frame[(i*grid_width):((i+1)*grid_width),(j*grid_height):((j+1)*grid_height)]
							lbins, abins, bbins = self._analyze_image(sub, fp, (self.frame_idx/stride_frames), grid_lab, lab_min, lab_max, grid_l_star, grid_a_star, grid_b_star, grid_mask, l_histo, a_histo, b_histo, i, j, 1, 1., thresh=ap['threshold'])

						# display stage (gridded)
						if ap['display']:
							for  d in range (dims):
								# for all the bins, get the value, and scale to the size of the grid
								lval, aval, bval = int(lbins[d]*255.), int(abins[d]*255.), int(bbins[d]*255.)
								#draw the rectangle in the wanted color
								self.make_rectangles(cv.fromarray(histimg), six_points, 6, i, j, d, [lval, aval, bval], grid_height_ratio, [lcolors, acolors, bcolors], voffset=0)
				
				#### SHOW
				if ap['display']:
					cv.ShowImage('Image', cv.fromarray(frame))
					cv.ShowImage('Histogram', cv.fromarray(histimg))
				fp.flush()
				self.frame_idx += 1
				
			elif (self.frame_idx%stride_frames) == 1:
				self.capture.set(cv.CV_CAP_PROP_POS_FRAMES, int((self.frame_idx / stride_frames) + 1) * stride_frames)
				self.frame_idx += stride_hop # stride_hop = 5 = stride - 1
				
			
			# no need to waitkey if we are not displaying:
			if ap['display']:
				# handle events
				k = cv.WaitKey (int(1000 / ap['afps']))
				if k % 0x100 == 27:
					# user has press the ESC key, so exit
						break
			
		del fp
		if ap['display']:
			cv.DestroyWindow('Image')
			cv.DestroyWindow('Histogram')