Exemple #1
0
        public void Copy(CImage image, int full)
        {
            width  = image.width;
            height = image.height;
            N_Bits = image.N_Bits;
            Grid   = new byte[width * height * (N_Bits / 8)];
            for (int i = 0; i < 256; i++)
            {
                Palette[i] = image.Palette[i];
            }

            if (full == 1)
            {
                for (int i = 0; i < width * height * (N_Bits / 8); i++)
                {
                    Grid[i] = image.Grid[i];
                }
            }
        }
Exemple #2
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 *****************************************
Exemple #3
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 *****************************************
        private void button1_Click(object sender, EventArgs e) // Open image
        {
            label1.Visible = false;
            label2.Visible = false;
            label3.Visible = false;

            OpenFileDialog openFileDialog1 = new OpenFileDialog();

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    OrigBmp       = new Bitmap(openFileDialog1.FileName);
                    OpenImageFile = openFileDialog1.FileName;
                    Number        = 0;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: Could not read file from disk. Original error: " +
                                    ex.Message);
                }
            }
            else
            {
                return;
            }

            double ScaleX = (double)pictureBox1.Width / OrigBmp.Width;
            double ScaleY = (double)pictureBox1.Height / OrigBmp.Height;

            if (ScaleX < ScaleY)
            {
                Scale1 = ScaleX;
            }
            else
            {
                Scale1 = ScaleY;
            }
            Drawn = false;

            progressBar1.Maximum = 100;
            progressBar1.Value   = 0;
            progressBar1.Step    = 1;
            progressBar1.Visible = true;

            label1.Text    = "Opened image: " + OpenImageFile;
            label1.Visible = true;

            OrigIm = new CImage(OrigBmp.Width, OrigBmp.Height, 24);

            OrigIm.denomProg = progressBar1.Maximum / progressBar1.Step;
            OrigIm.nLoop     = 2;
            if (OrigBmp.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                OrigIm.BitmapToImageOld(OrigBmp, this);
                Indexed = true;
            }
            else
            if (OrigBmp.PixelFormat == PixelFormat.Format24bppRgb)
            {
                OrigIm.BitmapToImage(OrigBmp, this);
                Indexed = false;
            }
            else
            {
                MessageBox.Show("Inappropriate pixel format=" + OrigBmp.PixelFormat);
                return;
            }

            BmpPictBox1 = new Bitmap(OrigBmp.Width, OrigBmp.Height, PixelFormat.Format24bppRgb);
            if (Indexed)
            {
                OrigIm.ImageToBitmapOld(BmpPictBox1, this);
            }
            else
            {
                OrigIm.ImageToBitmap(BmpPictBox1, this);
            }

            pictureBox1.Image = BmpPictBox1;
            g1 = Graphics.FromImage(BmpPictBox1);


            BmpPictBox2       = new Bitmap(OrigBmp.Width, OrigBmp.Height, PixelFormat.Format24bppRgb);
            pictureBox2.Image = BmpPictBox2;
            g2 = Graphics.FromImage(BmpPictBox2);



            pictureBox1.Image = OrigBmp;

            progressBar1.Visible = false;
            progressBar1.Maximum = 100;
            progressBar1.Step    = 1;
            OrigIm.denomProg     = progressBar1.Maximum / progressBar1.Step;
            ResultIm             = new CImage(OrigBmp.Width, OrigBmp.Height, 24);

            marginX        = (pictureBox1.Width - (int)(Scale1 * OrigIm.width)) / 2;   // space left of the image
            marginY        = (pictureBox1.Height - (int)(Scale1 * OrigIm.height)) / 2; // space above the image
            label2.Visible = true;
            OPEN           = true;
            CLICK          = false;
        } //********************************* end Open image *********************************