예제 #1
0
        /// <summary>
        /// Расчитывает матрицу перехода
        /// Взято здесь http://jepsonsblog.blogspot.ru/2012/11/rotation-in-3d-using-opencvs.html
        /// </summary>
        private void calculateTransformationMatrix(CoordinatesTransformer transformer)
        {
            // Матрица поворота 3x3
            CvMat R3x3 = new CvMat(3, 3, MatrixType.F64C1);

            Cv.Rodrigues2(transformer.Rotation, R3x3);

            // Произведение матрицы поворота и матрицы переноса
            CvMat RxT = new CvMat(4, 4, MatrixType.F64C1, new double[, ]
            {
                { R3x3[0, 0], R3x3[0, 1], R3x3[0, 2], transformer.Translation[0, 0] },
                { R3x3[1, 0], R3x3[1, 1], R3x3[1, 2], transformer.Translation[0, 1] },
                { R3x3[2, 0], R3x3[2, 1], R3x3[2, 2], transformer.Translation[0, 2] },
                { 0, 0, 0, 1 },
            });

            CvMat A1 = new CvMat(4, 3, MatrixType.F64C1, new double[, ]
            {
                { 1, 0, 0 },
                { 0, 1, 0 },
                { 0, 0, 0 },
                { 0, 0, 1 }
            });

            CvMat A2 = new CvMat(3, 4, MatrixType.F64C1, new double[, ]
            {
                { transformer.Intrinsic[0, 0], 0, transformer.Intrinsic[0, 2], 0 },
                { 0, transformer.Intrinsic[1, 1], transformer.Intrinsic[1, 2], 0 },
                { 0, 0, 1, 0 },
            });

            CvMat InvTransformationMatrix = (A2 * (RxT * A1));

            InvTransformationMatrix.Invert(transformer.TransformationMatrix);
        }
예제 #2
0
        /// <summary>
        /// Конструктор
        /// </summary>
        /// <param name="deviceId">ID камеры которая будет использоваться для получения изображения</param>
        /// <param name="frameSize">Размер изображения которое будет обрабатываться</param>
        public ImageProcessingRoutine(int deviceId, CvSize frameSize)
        {
            Camera = new WebCam(deviceId, frameSize);
            Calibrator = new CameraCalibrator(Camera.FrameSize);
            Finder = new ContoursFinder(Camera.FrameSize);
            Transformer = new CoordinatesTransformer();

            routineThread = new Thread(routine);
            routineThread.IsBackground = true;
            routineThread.Start();
        }
        /// <summary>
        /// Конструктор
        /// </summary>
        /// <param name="deviceId">ID камеры которая будет использоваться для получения изображения</param>
        /// <param name="frameSize">Размер изображения которое будет обрабатываться</param>
        public ImageProcessingRoutine(int deviceId, CvSize frameSize)
        {
            Camera      = new WebCam(deviceId, frameSize);
            Calibrator  = new CameraCalibrator(Camera.FrameSize);
            Finder      = new ContoursFinder(Camera.FrameSize);
            Transformer = new CoordinatesTransformer();

            routineThread = new Thread(routine);
            routineThread.IsBackground = true;
            routineThread.Start();
        }
예제 #4
0
        /// <summary>
        /// Пытается произвести калибровку камеры
        /// </summary>
        /// <returns>Результат калибровки</returns>
        public bool TryToCalibrate(out CoordinatesTransformer transformer)
        {
            CvPoint2D32f[] imageCornersArray;
            transformer = new CoordinatesTransformer();

            // Пытаемся найти углы шахматной доски
            if (FindCorners(out imageCornersArray))
            {
                // Преобразуем массивы точек в матрицы
                CvMat imageCorners = new CvMat(imageCornersArray.Length, 1, MatrixType.F32C2, imageCornersArray);
                CvMat numCorners   = new CvMat(1, 1, MatrixType.S32C1, new CvScalar(imageCornersArray.Length));

                // Определяем нужно-ли считать коэффициенты дисторсии
                CalibrationFlag flag = UseUndistort ? CalibrationFlag.RationalModel : CalibrationFlag.ZeroTangentDist | CalibrationFlag.FixK1 | CalibrationFlag.FixK2;

                // Производим калибровку
                Cv.CalibrateCamera2
                (
                    generateCorners(),
                    imageCorners,
                    numCorners,
                    chessBoard.Size,
                    transformer.Intrinsic,
                    transformer.Distortion,
                    transformer.Rotation,
                    transformer.Translation,
                    flag
                );

                // Определяем прямоугольник в котором произведена калибровка
                CalibratedZone[0] = imageCornersArray[0];
                CalibratedZone[1] = imageCornersArray[CornersPattern.Width - 1];
                CalibratedZone[2] = imageCornersArray.Last();
                CalibratedZone[3] = imageCornersArray[CornersPattern.Width * (CornersPattern.Height - 1)];

                // Расчитываем матрицу перехода
                calculateTransformationMatrix(transformer);

                return(true);
            }

            return(false);
        }
예제 #5
0
        /// <summary>
        /// Расчитывает матрицу перехода
        /// Взято здесь http://jepsonsblog.blogspot.ru/2012/11/rotation-in-3d-using-opencvs.html
        /// </summary>
        private void calculateTransformationMatrix(CoordinatesTransformer transformer)
        {
            // Матрица поворота 3x3
            CvMat R3x3 = new CvMat(3, 3, MatrixType.F64C1);
            Cv.Rodrigues2(transformer.Rotation, R3x3);

            // Произведение матрицы поворота и матрицы переноса
            CvMat RxT = new CvMat(4, 4, MatrixType.F64C1, new double[,]
            {
                {R3x3[0, 0], R3x3[0, 1], R3x3[0, 2], transformer.Translation[0, 0]},
                {R3x3[1, 0], R3x3[1, 1], R3x3[1, 2], transformer.Translation[0, 1]},
                {R3x3[2, 0], R3x3[2, 1], R3x3[2, 2], transformer.Translation[0, 2]},
                {0,          0,          0,          1                },
            });

            CvMat A1 = new CvMat(4, 3, MatrixType.F64C1, new double[,]
            {
                {1, 0, 0},
                {0, 1, 0},
                {0, 0, 0},
                {0, 0, 1}
            });

            CvMat A2 = new CvMat(3, 4, MatrixType.F64C1, new double[,]
            {
                {transformer.Intrinsic[0, 0], 0,                           transformer.Intrinsic[0, 2], 0},
                {0,                           transformer.Intrinsic[1, 1], transformer.Intrinsic[1, 2], 0},
                {0,                           0,                            1,                          0},
            });

            CvMat InvTransformationMatrix = (A2 * (RxT * A1));
            InvTransformationMatrix.Invert(transformer.TransformationMatrix);
        }
예제 #6
0
        /// <summary>
        /// Пытается произвести калибровку камеры
        /// </summary>
        /// <returns>Результат калибровки</returns>
        public bool TryToCalibrate(out CoordinatesTransformer transformer)
        {
            CvPoint2D32f[] imageCornersArray;
            transformer = new CoordinatesTransformer();

            // Пытаемся найти углы шахматной доски
            if (FindCorners(out imageCornersArray))
            {
                // Преобразуем массивы точек в матрицы
                CvMat imageCorners = new CvMat(imageCornersArray.Length, 1, MatrixType.F32C2, imageCornersArray);
                CvMat numCorners = new CvMat(1, 1, MatrixType.S32C1, new CvScalar(imageCornersArray.Length));

                // Определяем нужно-ли считать коэффициенты дисторсии
                CalibrationFlag flag = UseUndistort ? CalibrationFlag.RationalModel : CalibrationFlag.ZeroTangentDist | CalibrationFlag.FixK1 | CalibrationFlag.FixK2;

                // Производим калибровку
                Cv.CalibrateCamera2
                (
                    generateCorners(),
                    imageCorners,
                    numCorners,
                    chessBoard.Size,
                    transformer.Intrinsic,
                    transformer.Distortion,
                    transformer.Rotation,
                    transformer.Translation,
                    flag
                );

                // Определяем прямоугольник в котором произведена калибровка
                CalibratedZone[0] = imageCornersArray[0];
                CalibratedZone[1] = imageCornersArray[CornersPattern.Width - 1];
                CalibratedZone[2] = imageCornersArray.Last();
                CalibratedZone[3] = imageCornersArray[CornersPattern.Width * (CornersPattern.Height - 1)];

                // Расчитываем матрицу перехода
                calculateTransformationMatrix(transformer);

                return true;
            }

            return false;
        }