Пример #1
0
def test_direct_projection_undistortion():
    """
    Test the direct applicaiton of the undistortion model compared to the opencv provided one.
    """
    point = np.array([0.5, 0.5, 1.0])
    undistort = Undistort(np.array([[300, 0, 640], [0, 300, 480], [0, 0, 1]]),
                          np.array([0.1, 0.05, -0.002, 0.002, 0.001]))
    point_cv = undistort.project_point_with_distortion_cv(point)
    point_direct = undistort.project_point_with_distortion(point)

    np.testing.assert_array_almost_equal(point_cv, point_direct)
Пример #2
0
def test_bad_initialization():
    """
    Test initializer with bad values
    """
    with pytest.raises(TypeError):
        Undistort(np.identity(3), "not a matrix")
    with pytest.raises(TypeError):
        Undistort("not a matrix", [1, 2, 3, 4, 5])
    with pytest.raises(RuntimeError):
        Undistort(np.identity(4), [1, 2, 3, 4, 5])
    with pytest.raises(RuntimeError):
        Undistort(np.identity(3), [1, 2, 3, 4])
Пример #3
0
def test_file_saving_loading():
    """
    Test the file saving and loading.
    """
    undistort = Undistort(camera_matrix=np.identity(3),
                          distortion=[0, 0, 0, 1, 2])
    with tempfile.NamedTemporaryFile() as fid:
        undistort.write_file(fid.name)
        new_object = Undistort.read_json_file(fid.name)
        assert isinstance(new_object, Undistort)
        assert np.identity(3) == pytest.approx(new_object.camera_matrix)
        assert [0, 0, 0, 1, 2] == pytest.approx(new_object.distortion)
Пример #4
0
def sensor_calibration():
    """
    Method for getting and setting the sensor cal file.
    """
    success = True
    message = ""
    if request.method == "POST":
        cal_file = request.json
        try:
            sensor_cal = json.loads(cal_file,
                                    JSONDecoder=decode_sensor_settings)
            sensor_cal.write_file(SENSOR_CAL_FILE)
        except:
            success = False
            message = "Failed to parse passed sensor calibration."
        return jsonify({"success": success, "message": message})
    else:
        try:
            sensor_cal = Undistort.read_json_file(SENSOR_CAL_FILE)
        except:
            sensor_cal = None
            success = False
            message = "Failed to load sensor xml file."
        return jsonify({
            "sensor_cal_file": sensor_cal,
            "success": success,
            "message": message
        })
Пример #5
0
def test_default_initializer():
    """
    Defaults test
    """
    undistort = Undistort(camera_matrix=np.identity(3),
                          distortion=[0, 0, 0, 1, 2])
    assert np.identity(3) == pytest.approx(undistort.camera_matrix)
    assert [0, 0, 0, 1, 2] == pytest.approx(undistort.distortion)
Пример #6
0
def point_residuals(params, points_3d, points_2d):
    """
    Get residuals of projected 3d points, compared to the imaged points (two points for each points)
    """
    cam_matrix, distortion, rvec, tvec = unpack_params(params)
    undistort = Undistort(cam_matrix, distortion)
    transform = Transform(rotation=rvec, translation=tvec)
    residuals = np.array([
        get_projected(point_3d, undistort, transform) - point_2d
        for point_3d, point_2d in zip(points_3d, points_2d)
    ])
    return residuals.ravel()
Пример #7
0
def test_get_projected():
    """
    Test the projection function again opencv
    """
    rvec=np.array(initial_R, dtype="float32")
    tvec=np.array(initial_t, dtype="float32")
    undistorter=Undistort(initial_camera_matrix, initial_distortion)
    transformer=Transform(rvec, tvec)
    _, translations, points_2d = generate_dataset()

    for point_2d, point_3d in zip (points_2d, translations):
        point = sc.get_projected(point_3d, undistorter, transformer)
        np.testing.assert_array_almost_equal( point_2d, point, decimal=4 )
Пример #8
0
def generate_dataset():
    """
    Generate the 3d points, translations of the stage to get there and 2d point correspondences. 
    """
    initial_point = np.array([0, 0, 0])
    initial_U = Undistort(initial_camera_matrix, initial_distortion)
    initial_T = Transform (rotation=initial_R, translation=initial_t)

    #distance: 1.5 cm, FOV Width: (0.17920477879410118, 0.10080268807168191) cm
    #distance: 2 cm, FOV Width: (0.23893970505880158, 0.13440358409557587) cm
    #distance: 2.5 cm, FOV Width: (0.29867463132350197, 0.16800448011946983) cm
    distances = np.array([1.5, 2.0, 2.5]) - initial_t[2]
    width_x = [0.175, 0.23, 0.29]
    width_y = [0.10, 0.13, 0.16]

    translations = []
    for d, w, h in zip(distances, width_x, width_y):
        for x in np.arange(-w, w, w/10):
            for y in np.arange(-h, h, h/10):
                translations.append(np.array([x, y, d]))
    
    points_3d = []
    points_2d = []
    trans_out = []
    for t in translations:
        T = Transform(translation=t)
        point_3d = initial_T.transform_point(T.transform_point(initial_point))
        point_2d = initial_U.project_point_with_distortion(point_3d)

        if np.abs(point_2d[0]) > initial_camera_matrix[0, 2] or np.abs(point_2d[1]) > initial_camera_matrix[1, 2]:
            continue
        
        points_3d.append(point_3d)
        points_2d.append(point_2d)
        trans_out.append(t)

    return (points_3d, trans_out, points_2d)
Пример #9
0
def calibrate_from_3d_points(points_3d,
                             observed_points_2d,
                             camera_matrix=None,
                             distortion=None,
                             rvec=None,
                             tvec=None):
    """
    Given a set of points in 3d, the observed points in 2d, solve for the camera parameters and inital R and t.
    """
    if not isinstance(camera_matrix, np.ndarray):
        camera_matrix = np.array([[4000, 0, 650], [0, 4000, 350], [0, 0, 1]])
    if not isinstance(distortion, np.ndarray):
        distortion = np.array([0, 0, 0, 0, 0])
    if not isinstance(rvec, np.ndarray):
        rvec = np.array([0, 0, 0])
    if not isinstance(tvec, np.ndarray):
        tvec = np.array([0.005, -0.002, 0.0237])

    parameters = [
        camera_matrix[0, 0], camera_matrix[1, 1], camera_matrix[0, 2],
        camera_matrix[1, 2], distortion[0], distortion[1], distortion[2],
        distortion[3], distortion[4], rvec[0], rvec[1], rvec[2], tvec[0],
        tvec[1], tvec[2]
    ]

    #res = so.least_squares(point_residuals, parameters, jac="3-point", x_scale='jac', method='trf', loss='linear', verbose=2, args=(points_3d, observed_points_2d))
    res = so.minimize(single_residual,
                      parameters,
                      args=(points_3d, observed_points_2d),
                      method="Powell",
                      options={"disp": True})
    print("Actual Fit:")
    if res.success:
        print("Fit sucessful.")
    else:
        print("Fit failed.")
    camera_matrix, distortion, rvecs, tvecs = unpack_params(res.x)

    print("Camera Matrix:")
    print(camera_matrix)
    print("Distortion Matrix")
    print(distortion)
    print("rvec")
    print(rvecs)
    print("tvec")
    print(tvecs)

    return (Undistort(camera_matrix,
                      distortion), camera_matrix, distortion, rvec, tvec)
Пример #10
0
            file_stem = Path(an_image).stem
            pos = float(re.findall(r'(\d+(?:\.\d+)?)', file_stem)[1])
            image = cv2.imread(an_image)
            image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
            print("Loaded {} at height {}".format(an_image, pos))
            current_points_total = finder.process(image_gray)
            current_points_filtered = reject_outlier(
                np.asarray(current_points_total))
            if args.preview:
                overlayed_image = point_overlay(image, current_points_filtered)
                resized_image = cv2.resize(overlayed_image, (750, 750))
                cv2.imshow('image', resized_image)
                cv2.waitKey(0)
                cv2.destroyAllWindows()
            data_points_list.append(current_points_filtered)
            distance_list.append(pos / 1000.0)  #Convert mm to m.

    undistort = Undistort.read_json_file(args.input_intrinsics_file)
    if not undistort:
        print("Could not load camera parameters from " +
              args.input_intrinsics_file + ". Exiting...")
        sys.exit()

    fitter = LaserFitter(undistort, data_points_list, distance_list)
    res, laser_plane = fitter.process()

    print(res)
    print(laser_plane)

    laser_plane.write_file(args.output_file)
Пример #11
0
import argparse
import sys
from volteracamera.analysis.undistort import Undistort
from volteracamera.analysis.plane import Plane
from volteracamera.analysis.laser_line_finder import LaserProcessingServer

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("camera_parameters", type=str, help="json file containing undistortion class.")
    parser.add_argument("laser_plane", type=str, help="json file containing laser plane class.")
    parser.add_argument("-o", "--output_file", type=str, help="optional output file for the laser data, saved in csv format.")

    args = parser.parse_args()

    #load in the calibration files
    cam_params = Undistort.read_json_file(args.camera_parameters)
    laser_plane = Plane.read_json_file(args.laser_plane)

    output_file = args.output_file

    if cam_params is None:
        print ("Failed to load camera parameters. Exiting...")
        sys.exit()
    if laser_plane is None:
        print ("Failed to load laser plane parameters. Exiting...")
        sys.exit()

    laser_processor = LaserProcessingServer (cam_params, laser_plane)

    if output_file:
        laser_processor.save_data (output_file)