Esempio n. 1
0
    def test_record_calib_imgs_member_data():
        """
        Test member data assignment inside of `record_calib_imgs`

        `record_calib_imgs` is called with a negative countdown to force
        immediate chessboard logging. The test calibration images provided
        should all have valid chessboards for the provided params.
        """
        # Setup
        h, w, _ = cv_imread(testdir+'/raw/f00001.jpg').shape
        nf = len([
            f for f in listdir(testdir+'/raw') if f[-4:].lower() == '.jpg'
        ])

        # Tests
        calib = CalibratePSEye()
        calib.init_chessboard(p, o)
        try:
            calib.record_calib_imgs(
                cam=testdir+'/raw/f%05d.jpg', nframes=nf, countdown=-1
            )
            if calib.w != w:
                raise RuntimeError('\'w\' wasn\'t set properly')
            if calib.h != h:
                raise RuntimeError('\'h\' wasn\'t set properly')
            if calib.img_arr.shape != (h,w,1,nf):
                raise RuntimeError('\'img_arr.shape\' wasn\'t set properly')
            if calib.img_arr.dtype != uint8:
                raise RuntimeError('\'img_arr.dtype\' wasn\'t set properly')
        finally:
            calib.removepath()
Esempio n. 2
0
    def test_record_calib_imgs_paths():
        """
        Test record_calib_imgs path creation/checking.

        `record_calib_imgs` is called with a negative countdown to force
        immediate chessboard logging. The test calibration images provided
        should all have valid chessboards for the provided params.
        """
        global p, o
        nf = len([
            f for f in listdir(testdir+'/raw') if f[-4:].lower() == '.jpg'
        ])
        calib = CalibratePSEye()
        calib.init_chessboard(p, o)
        try:
            calib.record_calib_imgs(
                cam=testdir+'/raw/f%05d.jpg', nframes=nf, countdown=-1
            )

            # Make sure everything was created properly
            for p in ('/raw', '/corners'):
                if not isdir(calib.calibpath + p):
                    raise RuntimeError('\'%s\' wasn\'t created')

            # Make sure raw images were handled correctly
            #   never actually checks for frame equality - keep running into
            #   jpgs quality loss issues that honestly weren't worth the time
            #   I spent trying to fix them
            fns1 = sorted(listdir(testdir + '/raw'))
            fns2 = sorted(listdir(calib.calibpath + '/raw'))
            if len(fns1) != len(fns2):
                raise RuntimeError('Failed to save all valid calibration images')

        finally:
            calib.removepath()
Esempio n. 3
0
    def test_load_calib_imgs_paths():
        """
        Test load_calib_imgs path creation/checking.

        All `calib_imgs_paths` tests are basically the same
        """
        global p, o
        if not os_exists(testdir+'/raw'):
            raise RuntimeError('test \'raw\' directory could not be found')
        # Setup
        calib = CalibratePSEye()
        calib.init_chessboard(p, o)
        try:
            calib.load_calib_imgs(testdir+'/raw')

            # Make sure everything was created properly
            for p in ('/raw', '/corners'):
                if not isdir(calib.calibpath + p):
                    raise RuntimeError('path \'%s\' wasn\'t created')

            # Make sure raw images were copied correctly
            for fn in listdir(testdir + '/raw'):
                f1 = calib.calibpath + '/raw/' + fn
                f2 = testdir + '/raw/' + fn
                g1 = cv_imread(f1)
                i2 = cv_imread(f2)
                g2 = cvtColor(cvtColor(i2, COLOR_RGB2GRAY), COLOR_GRAY2RGB)
                if not array_equal(g1, g2):
                    raise RuntimeError('frame \'%s\' did not match' % fn)
                debug('\'%s\' matched' % fn)
        finally:
            calib.removepath()
Esempio n. 4
0
    def test_save_calibrations():
        """
        Test save_calibrations.

        Loading calibs was already tested above, so can rely on it.

        CSV FORMAT
            - delimiter: ', '
            - no floats, round and convert to int using known precision
            - strings in double quotes

            e.g. "varname", var[0], var[1], ...\\n
        """
        fn_cp = calibsdir + '/camera_params.csv'
        if not os_exists(fn_cp):
            raise RuntimeError('tests/camera_params.csv could not be found')
        # set not to tests/ (`load_calibrations` will do that)
        #   don't want to overwrite test data
        calib1 = CalibratePSEye()
        calib1.init_chessboard(p, o)
        try:
            # Load known calibs and then save
            cp = calib1.calibpath
            debug('%s' % calib1.calibpath)
            calib1.load_calibrations(fn_cp)
            calib1.calibpath = cp
            calib1.save_calibrations()
            if not os_exists(calib1.calibpath):
                raise RuntimeError('Failed to create calib path \'%s\''
                                   % calib1.calib_path)
            # Compare saving
            with open(fn_cp, 'r') as f:
                f1 = f.read()
            with open(cp+'/camera_params.csv', 'r') as f:
                f2 = f.read()
            if f1 != f2:
                raise RuntimeError('Camera parameter csvs did not match')

            # Compare loading
            calib2 = CalibratePSEye()
            calib2.load_calibrations(calib1.calibpath+'/camera_params.csv')
            paramlist = ('cameraMatrix', 'distCoeffs')
            for k in paramlist:
                k1 = getattr(calib1, k)
                k2 = getattr(calib2, k)
                if not array_equal(k1, k2):
                    raise RuntimeError(
                        'param \'%s\' does not match between calib1 and calib2' % k
                    )
                debug('\'%s\' matched' % k)
        finally:
            calib1.removepath()
Esempio n. 5
0
 def test_init_chessboard_str():
     """
     Test initializing based off of filepaths.
     """
     pstr = calibsdir + '/processing_params.csv'
     ostr = calibsdir + '/objp.csv'
     if not os_exists(pstr) or not os_exists(ostr):
         raise RuntimeError('Bad test files \'%s\' and \'%s\'' % (pstr, ostr))
     # Read String Files
     with open(ostr, 'r') as f:
         text = f.read()
         data = text.split(', ')
         shape = [int(v) for v in data[0].replace('\"', '').split('x')]
         objp = reshape([int(v) for v in data[1:]], shape).astype('float32')
     with open(pstr, 'r') as f:
         lines = f.read().splitlines()
         param_text = [line.split(', ') for line in lines]
         params = dict()
     for p in param_text:
         name = p[0].replace('\"', '')
         if name not in ('boardsize', 'zerozone', 'winsize', 'criteria'):
             continue
         if name == 'boardsize':
             params[name] = (int(p[1]), int(p[2]))
         elif name == 'zerozone':
             params[name]= (int(p[1]), int(p[2]))
         elif name == 'winsize':
             params[name] = (int(p[1]), int(p[2]))
         elif name == 'criteria':
             # first value should be single-digit number
             #   use that to determine decimal place shift
             powshift = -int(log10(int(p[1])))
             params[name] = (
                 int(int(p[1]) * 10**powshift),  # mode (int)
                 int(int(p[2]) * 10**powshift),  # something about pixels (int)
                 int(p[3]) * 10**powshift        # EPS termination (float)
             )
     # Test
     calib = CalibratePSEye()
     calib.init_chessboard(pstr, ostr)
     try:
         if calib.calibpath is None:
             raise RuntimeError('_calib_path wasn\'t created')
         for k in params.keys():
             if not getattr(calib, k) == params[k]:
                 raise RuntimeError('\'%s\' param was loaded incorrectly' % k)
             debug('\'%s\' param matched' % k)
         if not array_equal(calib.objp, objp):
             raise RuntimeError('Failed to load objp correctly')
     finally:
         calib.removepath()
Esempio n. 6
0
    def test_create_calib_path():
        """
        Test creation of calibration storage path.

        EXCEPTIONS
            RuntimeError if failed to remove calibration directory
        """
        calib = CalibratePSEye()
        calib.init_chessboard(p, o)
        if not isdir(calib.calibpath):  # ensure creation
            raise RuntimeError('Failed to create _calib_path')
        time_str = strftime('%Y%m%d-%H%M%S', localtime())  # test timestamp
        if not time_str[:-2] == calib.calibpath[-15:-2]:
            raise RuntimeError('_calib_path timestamp doesn\'t match to current minute')
        calib.removepath()
Esempio n. 7
0
    def test_get_timestamp():
        """
        Test retrieval of calib path timestamp

        EXCEPTIONS
            RuntimeError if failed to remove calibration directory
        """
        calib = CalibratePSEye()
        calib.init_chessboard(p, o)
        time_str = strftime('%Y%m%d-%H%M%S', localtime())  # test timestamp
        if not calib.calibpath[-15:] == calib.get_timestamp():
            raise RuntimeError('Error getting timestamp')
        if not time_str[:-2] == calib.get_timestamp()[:-2]:
            raise RuntimeError(
                'Retrieved timestamp doesn\'t match to minute - check `test_create_calib_path`'
            )
        calib.removepath()
Esempio n. 8
0
 def test_init_chessboard_obj():
     """
     Test chessboard initialization with Python objects
     """
     calib = CalibratePSEye()
     calib.init_chessboard(p, o)
     try:
         if calib.calibpath is None:
             raise RuntimeError('_calib_path wasn\'t created')
         for k in p.keys():
             if not getattr(calib, k) == p[k]:
                 raise RuntimeError('\'%s\' param was loaded incorrectly' % k)
             debug('\'%s\' param matched' % k)
         if not array_equal(calib.objp, o):
             raise RuntimeError('Failed to load objp correctly')
     finally:
         calib.removepath()
Esempio n. 9
0
    def test_save_calib_params():
        """
        Test that calibration params are being saved correctly, by opening
        file and comparing results.

        Loading params is tested in `test_init_str`.
        """
        calib = CalibratePSEye()
        calib.init_chessboard(p, o)
        try:
            pstr = calib.calibpath + '/processing_params.csv'
            ostr = calib.calibpath + '/objp.csv'
            calib._load_processing_params(pstr)
            calib._load_objp(ostr)
            for k in p.keys():
                if getattr(calib, k) != p[k]:
                    raise RuntimeError('\'%s\' does not match' % k)
            debug('\'%s\' matched' % k)
            if not array_equal(o, calib.objp):
                raise RuntimeError('objp does not match')
        finally:
            calib.removepath()
Esempio n. 10
0
    def test_compute_calibrations():
        """
        Test computation to the 4th decimal place on known calibration data.
        """
        # Test Asserts
        calib = CalibratePSEye()
        calib.corners_arr = [1, 2]
        calib.objpoints = [1, 2]
        calib.w = 320
        calib.h = 240

        calib.corners_arr = []
        try:
            calib.compute_calibrations()
        except RuntimeError:
            pass
        else:
            raise RuntimeError('Failed to catch len(corners_arr)==0')

        calib.corners_arr = [1, 2]
        calib.objpoints = []
        try:
            calib.compute_calibrations()
        except RuntimeError:
            pass
        else:
            raise RuntimeError('Failed to catch len(objpoints)==0')

        calib.objpoints = [1, 2]
        calib.w = None
        try:
            calib.compute_calibrations()
        except RuntimeError:
            pass
        else:
            raise RuntimeError('Failed to catch _w is None')

        calib.h = None
        calib.w = 320
        try:
            calib.compute_calibrations()
        except RuntimeError:
            pass
        else:
            raise RuntimeError('Failed to catch h is None')

        # Test Math
        global cpdict
        imgpath = testdir + '/raw'
        if not os_exists(imgpath):
            raise RuntimeError('Could not find imgpath')
        calib = CalibratePSEye()
        calib.init_chessboard(p, o)
        calib.load_calib_imgs(imgpath)
        try:
            calib.compute_calibrations()
            calib.save_calibrations()
            for k in cpdict.keys():
                k1 = cpdict[k]  # already rounded b/c loaded from file
                k2 = around(getattr(calib, k), decimals=4)
                if not array_equal(k1, k2):
                    raise RuntimeError('\'%s\' did not match' % k)
                debug('\'%s\' matched' % k)
                # print(getattr(calib, k))
        finally:
            calib.removepath()
Esempio n. 11
0
    def test_verify_calib_params():
        """
        Test verify_calib_params asserts

        For int 2-tuples (boardsize, winsize, zerozone):
            Tests too many and then too few elements to ensure equality check
            Exact fit case was tested in the init testers above
            Tests catching of floats

        objp
            `assert self.objp.shape[0] == self.boardsize[0] * self.boardsize[1]`
            `assert self.objp.shape[1] == 3`
            Same testing rules as above
            Also checks for non-float32 types
        """
        global p, o
        # Test 2-tuples
        for k in ('boardsize', 'winsize', 'zerozone'):
            p[k] = (-1,-1,-1)
            try:
                calib = CalibratePSEye()
                calib.init_chessboard(p, o)
            except TypeError:
                pass
            else:
                raise RuntimeError('Failed to catch len(%s) too large' % k)
            finally:
                del calib

            p[k] = (-1,)
            try:
                calib = CalibratePSEye()
                calib.init_chessboard(p, o)
            except TypeError:
                pass
            else:
                raise RuntimeError('Failed to catch len(%s) too large' % k)
            finally:
                del calib

            p[k] = (-1.1,-1)
            try:
                calib = CalibratePSEye()
                calib.init_chessboard(p, o)
            except TypeError:
                pass
            else:
                raise RuntimeError('Failed to catch %s[0] non-int' % k)
            finally:
                del calib

            p[k] = (-1,-1.1)
            try:
                calib = CalibratePSEye()
                calib.init_chessboard(p, o)
            except TypeError:
                pass
            else:
                raise RuntimeError('Failed to catch %s[1] non-int' % k)
            finally:
                del calib

            p = {
                'boardsize': boardsize,
                'winsize': (11, 11),
                'zerozone': (-1, -1),
                'criteria': (
                    TERM_CRITERIA_EPS+TERM_CRITERIA_MAX_ITER,30,0.001
                )
            }

        p['criteria'] = (-1.1, -1, 5, 18)
        try:
            calib = CalibratePSEye()
            calib.init_chessboard(p, o)
        except TypeError:
            pass
        else:
            raise RuntimeError('Failed to catch len(criteria) too large')

        p['criteria'] = (-1,)
        try:
            calib = CalibratePSEye()
            calib.init_chessboard(p, o)
        except TypeError:
            pass
        else:
            raise RuntimeError('Failed to catch len(criteria) too small')

        # check float32 case (should pass)
        p['criteria'] = (3, 30, 0.001)
        calib = CalibratePSEye()
        calib.init_chessboard(p, o)
        calib.removepath()

        # check non float32 case (should fail)
        for t in ('uint8', 'uint16', 'uint32', 'uint64', 'int16', 'int32',
                  'int64', 'float64', 'object'):
            objp = o.astype(t)
            try:
                CalibratePSEye(p, objp)
            except TypeError:
                pass
            else:
                raise RuntimeError('Failed to catch objp non-float32')

        objp = o.copy()[...,newaxis]
        try:
            CalibratePSEye(p,objp)
        except TypeError:
            pass
        else:
            raise RuntimeError('Failed to catch objp too many dimensions')

        objp = zeros((boardsize[0]*boardsize[1]+1, 3))
        try:
            CalibratePSEye(p,objp)
        except TypeError:
            pass
        else:
            raise RuntimeError('Failed to catach objp[0] bad size')

        objp = o[:, :2].copy()
        try:
            CalibratePSEye(p, objp)
        except TypeError:
            pass
        else:
            raise RuntimeError('Failed to catach objp[1] too small')

        objp = zeros((o.shape[0], o.shape[1]+1))
        try:
            CalibratePSEye(p, objp)
        except TypeError:
            pass
        else:
            raise RuntimeError('Failed to catach objp[1] too large')