public void process() {
        while (!exited) {
            try {
                if (context.capturedFrames.size() > 0) {
                    final StereoFrame stereoFrame = context.capturedFrames.poll();
                    synchronized (context.capturedFrames) {
                        context.capturedFrames.notifyAll();
                    }

                    int width = stereoFrame.width;
                    int height = stereoFrame.height;

                    long startTimeMillis = System.currentTimeMillis();

                    int[] leftColors = stereoFrame.rightRawRgb;
                    int[] rightColors = stereoFrame.leftRawRgb;
                    int[] regionColors = new int[width*height];
                    int[] outputColors = new int[width*height];
                    int[] smoothedRightColors = new int[width*height];
                    int[] smoothedLeftColors = new int[width*height];
                    float[] gradient = new float[width*height];

                    Watersheding.smooth(width, height, rightColors, smoothedRightColors);
                    Watersheding.smooth(width, height, leftColors, smoothedLeftColors);
                    Watersheding.gradient(width, height, smoothedRightColors, gradient);
                    Watersheding.watershed(width, height, smoothedRightColors, gradient, regionColors);

                    final Map<Integer, Region> indexRegionMap = new HashMap<Integer, Region>();

                    StereoCorrelation.analyzeRegions(width, height, smoothedRightColors, regionColors,
                            stereoFrame.regions, indexRegionMap, 0.015f, 0.015f);
                    float correlation = StereoCorrelation.correlateRegions(width, height, smoothedLeftColors,
                            smoothedRightColors, stereoFrame.regions,
                            context.leftRedShift, context.leftGreenShift, context.leftBlueShift, context.leftYShift);

                    StereoCorrelation.renderRegions(width, height, indexRegionMap, leftColors, outputColors);

                    stereoFrame.leftRawRgb = smoothedLeftColors;
                    stereoFrame.rightRawRgb = smoothedRightColors;
                    stereoFrame.regionsRawRgb = regionColors;
                    stereoFrame.correlationsRawRgb = outputColors;

                    logger.info("Analysis took: " + (System.currentTimeMillis() -  startTimeMillis) + "ms.");
                    logger.info("Found regions: " + stereoFrame.regions.size()
                            + " Capture averaged over: " + stereoFrame.captureCount);
                    logger.info("Correlation: " + (((int) (correlation * 10000)) / 100f) + "%");

                    if (correlation < 0.90||(correlation < 0.98
                            && System.currentTimeMillis() - context.lastCalibrationMillis > 60000)) {
                        logger.info("Calibrating brightness due to low correction...");
                        calibrateStereoCorrelation(width, height, smoothedRightColors, smoothedLeftColors,
                                stereoFrame.regions, correlation);
                    }


                    context.analyzedFrames.put(stereoFrame);
                    synchronized (context.analyzedFrames) {
                        context.analyzedFrames.notifyAll();
                    }

                } else {
                    synchronized (context.capturedFrames) {
                        context.capturedFrames.wait();
                    }
                }
            } catch (InterruptedException e) {
                logger.debug("Interrupted.");
            } catch (Exception e) {
                logger.error("Error analysing frame.", e);
            }
        }
    }