Exemplo n.º 1
0
        }         //************************************ end Rect_Retain *****************************************

        public void Rect_Optimal(Point[] v, bool CUT, ref CImage Result)
        // Calculates the corners of the rectifyed image and then makes a bilinear transformation
        {
            int    MaxSize;
            double alphaX, alphaY, betaX, betaY, F, Height, phiX, phiY,
                   RedX, RedY, Width, M0X, M1X, M3Y, M2Y;

            M0X = (double)v[1].X + (v[0].X - v[1].X) * ((double)height / 2 - v[1].Y) / ((double)v[0].Y - v[1].Y);
            M1X = (double)v[2].X + (v[3].X - v[2].X) * ((double)height / 2 - v[2].Y) / ((double)v[3].Y - v[2].Y);
            M3Y = (double)v[0].Y + (v[3].Y - v[0].Y) * ((double)width / 2 - v[0].X) / ((double)v[3].X - v[0].X);
            M2Y = (double)v[1].Y + (v[2].Y - v[1].Y) * ((double)width / 2 - v[1].X) / ((double)v[2].X - v[1].X);

            RedY = (double)(v[3].Y - v[2].Y) / (double)(v[0].Y - v[1].Y);
            RedX = (double)(v[3].X - v[0].X) / (double)(v[2].X - v[1].X);
            if (width > height)
            {
                MaxSize = width;
            }
            else
            {
                MaxSize = height;
            }
            F      = 1.0 * (double)(MaxSize);
            alphaY = Math.Atan2(F, (double)(width / 2 - M0X));
            betaY  = Math.Atan2(F, (double)(M1X - width / 2));
            phiY   = Math.Atan2(RedY * Math.Sin(betaY) - Math.Sin(alphaY), Math.Cos(alphaY) + RedY * Math.Cos(betaY));

            alphaX = Math.Atan2(F, (double)(M3Y - height / 2));
            betaX  = Math.Atan2(F, (double)(height / 2 - M2Y));
            phiX   = Math.Atan2(RedX * Math.Sin(betaX) - Math.Sin(alphaX), Math.Cos(alphaX) + RedX * Math.Cos(betaX));
            double P0X = F * Math.Cos(alphaY) / Math.Sin(alphaY - phiY);
            double P1X = F * Math.Cos(betaY) / Math.Sin(betaY + phiY);
            double P0Y = F * Math.Cos(alphaX) / Math.Sin(alphaX + phiX);

            Width  = F * (Math.Cos(alphaY) / Math.Sin(alphaY - phiY) + Math.Cos(betaY) / Math.Sin(betaY + phiY));
            Height = F * (Math.Cos(alphaX) / Math.Sin(alphaX - phiX) + Math.Cos(betaX) / Math.Sin(betaX + phiX));

            if (Width < 0.0 || Height < 0.0)
            {
                MessageBox.Show("The clicked area does not contain the center of the image");
                return;
            }

            double OptCX = 0.0;
            double OptCY = 0.0;
            double CX    = Math.Tan(phiY);
            double CY    = Math.Tan(phiX);

            Optimization(F, v, CX, CY, ref OptCX, ref OptCY);
            CX = OptCX;
            CY = OptCY;

            CImage Out;

            if (CUT)
            {
                Out = new CImage((int)Width, (int)Height, N_Bits);
            }
            else
            {
                Out = new CImage(width, height, N_Bits);
            }
            Result.Copy(Out, 0);

            double A = 0.0, B, C, D, Det, E, G;

            double[] xc = new double[4];
            double[] yc = new double[4];
            double[] zc = new double[4];

            for (int i = 0; i < 4; i++)
            {
                A     = B = C = D = 0.0;
                A     = (F / (v[i].X - width / 2) + CX);
                B     = CY;
                C     = width / 2 * F / (v[i].X - width / 2) + CX * width / 2 + CY * height / 2 + F;
                D     = CX;
                E     = (F / (v[i].Y - height / 2) + CY);
                G     = height / 2 * F / (v[i].Y - height / 2) + CX * width / 2 + CY * height / 2 + F;
                Det   = A * E - B * D;
                xc[i] = (C * E - B * G) / Det;
                yc[i] = (A * G - C * D) / Det;
                zc[i] = F - CX * (xc[i] - width / 2) - CY * (yc[i] - height / 2); // corrected
            }

            double zz;
            double xp, yp, xp0, xp1, yp0, yp1, xf, yf;

            for (int Y = 0; Y < Result.height; Y++) //=========== over the rectified image ====================
            {
                xp0 = xc[1] + (xc[0] - xc[1]) * Y / (Result.height - 1);
                xp1 = xc[2] + (xc[3] - xc[2]) * Y / (Result.height - 1);

                for (int X = 0; X < Result.width; X++) //=====================================================
                {
                    yp0 = yc[1] + (yc[2] - yc[1]) * X / (Result.width - 1);
                    yp1 = yc[0] + (yc[3] - yc[0]) * X / (Result.width - 1);
                    xp  = xp0 + (xp1 - xp0) * X / (Result.width - 1);
                    yp  = yp0 + (yp1 - yp0) * Y / (Result.height - 1);
                    zz  = F - CX * (xp - width / 2) - CY * (yp - height / 2); // corrected
                    xf  = width / 2 + (xp - width / 2) * F / (F - CX * (xp - width / 2) - CY * (yp - height / 2));
                    yf  = height / 2 + (yp - height / 2) * F / (F - CX * (xp - width / 2) - CY * (yp - height / 2));

                    if ((int)xp >= 0 && (int)xp < width && (int)yp >= 0 && (int)yp < height)
                    {
                        if (N_Bits == 24)
                        {
                            for (int ic = 0; ic < 3; ic++)
                            {
                                Result.Grid[ic + 3 * X + 3 * Result.width * Y] = Grid[ic + 3 * (int)xf + 3 * width * (int)yf];
                            }
                        }
                        else
                        {
                            Result.Grid[X + Result.width * (Result.height - 1 - Y)] = Grid[(int)xf + width * (int)yf];
                        }
                    }
                } //================================ end for (X... ==============================
            }     //================================== end for (Y... ================================
        }         //************************************ end Rect_Optimal *****************************************
Exemplo n.º 2
0
        }         //************************************ end Rect_Central *****************************************

        public void Rect_Retain(Point[] v, bool CUT, double Rel, ref CImage Result)
        // Calculates the corners of the rectifyed image and then makes a bilinear transformation
        {
            int    MaxSize;
            double alphaX, alphaY, betaX, betaY, F, Height, phiX, phiY,
                   RedX, RedY, Width, M0X, M1X, M3Y, M2Y;

            M0X = (double)v[1].X + (v[0].X - v[1].X) * ((double)height / 2 - v[1].Y) / ((double)v[0].Y - v[1].Y);
            M1X = (double)v[2].X + (v[3].X - v[2].X) * ((double)height / 2 - v[2].Y) / ((double)v[3].Y - v[2].Y);
            M3Y = (double)v[0].Y + (v[3].Y - v[0].Y) * ((double)width / 2 - v[0].X) / ((double)v[3].X - v[0].X);
            M2Y = (double)v[1].Y + (v[2].Y - v[1].Y) * ((double)width / 2 - v[1].X) / ((double)v[2].X - v[1].X);

            RedY = (double)(v[3].Y - v[2].Y) / (double)(v[0].Y - v[1].Y);
            RedX = (double)(v[3].X - v[0].X) / (double)(v[2].X - v[1].X);
            if (width > height)
            {
                MaxSize = width;
            }
            else
            {
                MaxSize = height;
            }
            F      = 1.0 * (double)(MaxSize);
            alphaY = Math.Atan2(F, (double)(width / 2 - M0X));
            betaY  = Math.Atan2(F, (double)(M1X - width / 2));
            phiY   = Math.Atan2(RedY * Math.Sin(betaY) - Math.Sin(alphaY), Math.Cos(alphaY) + RedY * Math.Cos(betaY));

            alphaX = Math.Atan2(F, (double)(M3Y - height / 2));
            betaX  = Math.Atan2(F, (double)(height / 2 - M2Y));
            phiX   = Math.Atan2(RedX * Math.Sin(betaX) - Math.Sin(alphaX), Math.Cos(alphaX) + RedX * Math.Cos(betaX));

            double CX = Math.Tan(phiY); // X-coefficient of plane P
            double CY = Math.Tan(phiX); // Y-coefficient of plane

            double OptCX = 0.0, OptCY = 0.0;

            Optimization(F, v, CX, CY, ref OptCX, ref OptCY);
            CX = OptCX;
            CY = OptCY;

            double A = 0.0, B, C, D, Det, E, G;

            double[] xc = new double[8];
            double[] yc = new double[8];
            double[] zc = new double[8];

            Point[] w = new Point[8];
            for (int i = 0; i < 4; i++)
            {
                w[i] = v[i];
            }

            for (int i = 0; i < 4; i++)
            {
                A     = (F / (w[i].X - width / 2) + CX);
                B     = CY;
                C     = width / 2 * F / (w[i].X - width / 2) + CX * width / 2 + CY * height / 2 + F;
                D     = CX;
                E     = (F / (w[i].Y - height / 2) + CY);
                G     = height / 2 * F / (w[i].Y - height / 2) + CX * width / 2 + CY * height / 2 + F;
                Det   = A * E - B * D;
                xc[i] = (C * E - B * G) / Det;
                yc[i] = (A * G - C * D) / Det;
                zc[i] = F - CX * (xc[i] - width / 2) - CY * (yc[i] - height / 2); // corrected
            }
            // Transforming the points:
            for (int i = 0; i < 4; i++) // new points:
            {
                xc[i + 4] = (int)(width / 2 + Rel * (xc[i] - width / 2));
                yc[i + 4] = (int)(height / 2 + Rel * (yc[i] - height / 2));
                zc[i + 4] = (int)(F + Rel * (zc[i] - F));
            }

            Width =
                Math.Sqrt(Math.Pow((xc[7] - xc[4]), 2.0) + Math.Pow((yc[7] - yc[4]), 2.0) + Math.Pow((zc[7] - zc[4]), 2.0));
            Height =
                Math.Sqrt(Math.Pow((xc[4] - xc[5]), 2.0) + Math.Pow((yc[4] - yc[5]), 2.0) + Math.Pow((zc[4] - zc[5]), 2.0));

            CImage Out;

            Out = new CImage((int)Width, (int)Height, N_Bits);
            Result.Copy(Out, 0);

            double zz;
            double xp, yp, xp0, xp1, yp0, yp1, xf, yf;

            for (int Y = 0; Y < Result.height; Y++) //=========== over the rectified image ====================
            {
                xp0 = xc[5] + (xc[4] - xc[5]) * Y / (Result.height - 1);
                xp1 = xc[6] + (xc[7] - xc[6]) * Y / (Result.height - 1);

                for (int X = 0; X < Result.width; X++) //=====================================================
                {
                    yp0 = yc[5] + (yc[6] - yc[5]) * X / (Result.width - 1);
                    yp1 = yc[4] + (yc[7] - yc[4]) * X / (Result.width - 1);
                    xp  = xp0 + (xp1 - xp0) * X / (Result.width - 1);         // +100.0;
                    yp  = yp0 + (yp1 - yp0) * Y / (Result.height - 1);
                    zz  = F - CX * (xp - width / 2) - CY * (yp - height / 2); // correted
                    xf  = width / 2 + (xp - width / 2) * F / (F - CX * (xp - width / 2) - CY * (yp - height / 2));
                    yf  = height / 2 + (yp - height / 2) * F / (F - CX * (xp - width / 2) - CY * (yp - height / 2));

                    if ((int)xf >= 0 && (int)xf < width && (int)yf >= 0 && (int)yf < height)
                    {
                        if (N_Bits == 24)
                        {
                            for (int ic = 0; ic < 3; ic++)
                            {
                                Result.Grid[ic + 3 * X + 3 * Result.width * Y] =
                                    Grid[ic + 3 * (int)xf + 3 * width * (int)yf];
                            }
                        }
                        else
                        {
                            Result.Grid[X + Result.width * (Result.height - 1 - Y)] = Grid[(int)xf + width * (int)yf];
                        }
                    }
                } //================================ end for (X... ==============================
            }     //================================== end for (Y... ================================
        }         //************************************ end Rect_Retain *****************************************