Ejemplo n.º 1
0
        //最近邻插值
        public Color nearest_interp(myMat.myCoor source_p)
        {
            double i = (int)System.Math.Round(source_p.i);
            double j = (int)System.Math.Round(source_p.j);

            return(inputImg.getRGB(new myMat.myCoor(i, j)));
        }
Ejemplo n.º 2
0
        public myMat.myCoor bend_source_coor(myMat.myCoor aim_p, myMat.myCoor mid_p, double a_max, double radius)
        {
            /*
             * 弯曲变换,输入目标图中的坐标,返回原图坐标
             * aim_p: 目标图坐标
             * mid_p: 中点坐标
             * a_max: 最大旋转角度,弧度制
             * radius: 旋转半径
             */

            double dis = aim_p.getDis(mid_p);

            if (dis >= radius)
            {
                return(aim_p);
            }

            double a  = a_max * (radius - dis) / radius;
            int    x_ = (int)(aim_p.j - mid_p.j);
            int    y_ = (int)(aim_p.i - mid_p.i);

            myMat.myCoor ord = new myMat.myCoor();
            ord.j = x_ * System.Math.Cos(a) - y_ * System.Math.Sin(a);
            ord.j = ord.j + mid_p.j;
            ord.i = x_ * System.Math.Sin(a) + y_ * System.Math.Cos(a);
            ord.i = ord.i + mid_p.i;

            return(ord);
        }
Ejemplo n.º 3
0
        //双线性插值
        public Color bilinear_interp(myMat.myCoor source_p)
        {
            int x1 = (int)System.Math.Floor(source_p.i);
            int y1 = (int)System.Math.Floor(source_p.j);
            int x2 = x1 + 1;
            int y2 = y1 + 1;

            Byte[] f11 = inputImg.getRGB_Byte(new myMat.myCoor(x1, y1));
            Byte[] f12 = inputImg.getRGB_Byte(new myMat.myCoor(x1, y2));
            Byte[] f21 = inputImg.getRGB_Byte(new myMat.myCoor(x2, y1));
            Byte[] f22 = inputImg.getRGB_Byte(new myMat.myCoor(x2, y2));

            double[] fxy1 = new double[3];
            double[] fxy2 = new double[3];
            double[] fxy  = new double[3];

            for (int k = 0; k < 3; k++)
            {
                fxy1[k] = (x2 - source_p.i) / (x2 - x1) * (double)f11[k] + (source_p.i - x1) / (x2 - x1) * (double)f21[k];
                fxy2[k] = (x2 - source_p.i) / (x2 - x1) * (double)f12[k] + (source_p.i - x1) / (x2 - x1) * (double)f22[k];
            }
            for (int k = 0; k < 3; k++)
            {
                fxy[k] = (y2 - source_p.j) / (y2 - y1) * (double)fxy1[k] + (source_p.j - y1) / (y2 - y1) * (double)fxy2[k];
            }

            return(inputImg.getRGB_fromB(fxy));
        }
Ejemplo n.º 4
0
        //TPS变换得到目标图中第i行i列坐标对应原图中的坐标
        public myMat.myCoor TPS_get_sourceCoor(int i, int j)
        {
            double source_x = 0, source_y = 0;

            for (int k = 0; k < point_num; k++)
            {
                double dis = System.Math.Pow(i - aim_ps[k, 0], 2) + System.Math.Pow(j - aim_ps[k, 1], 2);
                if (dis == 0)
                {
                    dis += 1e-16;
                }
                double L_k = dis * System.Math.Log(dis) / 2;
                source_x += L_k * W[k, 0];
                source_y += L_k * W[k, 1];
            }

            source_x += W[point_num, 0] * 1;
            source_x += W[point_num + 1, 0] * i;
            source_x += W[point_num + 2, 0] * j;

            source_y += W[point_num, 1] * 1;
            source_y += W[point_num + 1, 1] * i;
            source_y += W[point_num + 2, 1] * j;

            myMat.myCoor sourceCoor = new myMat.myCoor(source_x, source_y);
            return(sourceCoor);
        }
Ejemplo n.º 5
0
        //旋转变换 返回原图中对应坐标点
        public myMat.myCoor Turn_get_sourceCoor(int i, int j, double turn_angle)
        {
            double x, y;

            x = i * System.Math.Cos(turn_angle) - j * System.Math.Sin(turn_angle);
            y = i * System.Math.Sin(turn_angle) + j * System.Math.Cos(turn_angle);
            myMat.myCoor sourceCoor = new myMat.myCoor(x, y);
            return(sourceCoor);
        }
Ejemplo n.º 6
0
 public Color interp(myMat.myCoor source_p, string interp_method)
 {
     if (interp_method == "最近邻")
     {
         return(nearest_interp(source_p));
     }
     else if (interp_method == "双线性")
     {
         return(bilinear_interp(source_p));
     }
     else
     {
         return(bicubic_interp(source_p));
     }
 }
Ejemplo n.º 7
0
        public myMat.myCoor ball_source_coor(myMat.myCoor aim_p, myMat.myCoor mid_p, double radius, int direction = 1)
        {
            /*
             * 球形畸变,输入目标图中的坐标,返回原图坐标
             * aim_p: 目标图坐标
             * mid_p: 中点坐标
             * radius: 畸变半径
             */

            double dis = aim_p.getDis(mid_p);

            int x_ = (int)(aim_p.j - mid_p.j);
            int y_ = (int)(aim_p.i - mid_p.i);

            myMat.myCoor ord = new myMat.myCoor();

            if (direction > 0) //桶形畸变
            {
                ord.j = radius / dis * System.Math.Asin(dis / radius) * x_;
                ord.i = radius / dis * System.Math.Asin(dis / radius) * y_;
            }
            else //枕形畸变
            {
                ord.j = dis / radius / System.Math.Asin(dis / radius) * x_;
                ord.i = dis / radius / System.Math.Asin(dis / radius) * y_;
            }

            ord.j = ord.j + mid_p.j;
            ord.i = ord.i + mid_p.i;

            if (double.IsNaN(ord.i))
            {
                ord.i = inputImg.height + 1000;
            }
            if (double.IsNaN(ord.j))
            {
                ord.j = inputImg.width + 1000;
            }

            return(ord);
        }
Ejemplo n.º 8
0
        public void bend_distort(double a_max, double radius, string interp_method = "最近邻")
        {
            /*
             * 弯曲变换,将结果赋予resultImg
             * a_max: 最大旋转角度,角度制
             * radius: 旋转半径
             */
            resultImg = new myMat();
            double a_max_arc = a_max * System.Math.PI / 180;

            myMat.myCoor mid_p = new myMat.myCoor(inputImg.height / 2, inputImg.width / 2);
            resultImg.init_bytes(inputImg.height, inputImg.width);
            for (int i = 0; i < inputImg.height; i++)
            {
                for (int j = 0; j < inputImg.width; j++)
                {
                    myMat.myCoor sourceCoor = bend_source_coor(new myMat.myCoor(i, j), mid_p, a_max_arc, radius);
                    Color        c          = interp(sourceCoor, interp_method);
                    resultImg.set_rgb(c, new myMat.myCoor(i, j));
                }
            }
        }
Ejemplo n.º 9
0
        //使用参数矩阵W求得目标图
        public void get_result_img(string interp_method)
        {
            myMat.myCoor source_leftUp_point   = new myMat.myCoor(in_i: sourceFace_distort.inputImg.height, in_j: sourceFace_distort.inputImg.width); //初始化为右下角点
            myMat.myCoor source_leftDown_point = new myMat.myCoor(in_i: 0, in_j: sourceFace_distort.inputImg.width);                                  //初始化为右上角点
            leftUp_point   = new myMat.myCoor();                                                                                                      //初始化为右下角点
            leftDown_point = new myMat.myCoor();                                                                                                      //初始化为右上角点
            myMat.myCoor vir_leftUp_point   = new myMat.myCoor(0, 0);
            myMat.myCoor vir_leftDown_point = new myMat.myCoor(sourceFace_distort.inputImg.height, 0);

            sourceFace_distort.resultImg = new myMat();
            sourceFace_distort.resultImg.init_bytes(sourceFace_distort.inputImg.height, sourceFace_distort.inputImg.width);
            for (int i = 0; i < sourceFace_distort.inputImg.height; i++)
            {
                for (int j = 0; j < sourceFace_distort.inputImg.width; j++)
                {
                    //得到目标图中第i行i列坐标对应原图中的坐标
                    myMat.myCoor sourceCoor = TPS_get_sourceCoor(i, j);

                    if (sourceCoor.i >= 0 && sourceCoor.j >= 0 && sourceCoor.i < sourceFace_distort.inputImg.height && sourceCoor.j < sourceFace_distort.inputImg.width)
                    {
                        if (myMat.myCoor.getDis(sourceCoor, vir_leftUp_point) < myMat.myCoor.getDis(source_leftUp_point, vir_leftUp_point))
                        {
                            source_leftUp_point.i = sourceCoor.i; source_leftUp_point.j = sourceCoor.j;
                            leftUp_point.i        = i; leftUp_point.j = j;
                        }

                        if (myMat.myCoor.getDis(sourceCoor, vir_leftDown_point) < myMat.myCoor.getDis(source_leftDown_point, vir_leftDown_point))
                        {
                            source_leftDown_point.i = sourceCoor.i; source_leftDown_point.j = sourceCoor.j;
                            leftDown_point.i        = i; leftDown_point.j = j;
                        }
                    }


                    Color c = sourceFace_distort.interp(sourceCoor, interp_method);
                    sourceFace_distort.resultImg.set_rgb(c, new myMat.myCoor(i, j));
                }
            }
        }
Ejemplo n.º 10
0
        //双三次插值
        public Color bicubic_interp(myMat.myCoor source_p)
        {
            //x y坐标的小数部分
            int    x1 = (int)System.Math.Floor(source_p.i);
            int    y1 = (int)System.Math.Floor(source_p.j);
            double dx = source_p.i - x1;
            double dy = source_p.j - y1;

            double[] result = new double[3] {
                0, 0, 0
            };
            double k_sum = 0;

            for (int x = -1; x <= 2; x++)
            {
                for (int y = -1; y <= 2; y++)
                {
                    double dis_x = System.Math.Abs(dx - x);
                    double dis_y = System.Math.Abs(dy - y);
                    double kx    = bsp_bicubic_k(dis_x);
                    double ky    = bsp_bicubic_k(dis_y);

                    Byte[] fxy = inputImg.getRGB_Byte(new myMat.myCoor(x1 + x, y1 + y));
                    k_sum += kx * ky;
                    for (int k = 0; k < 3; k++)
                    {
                        result[k] += fxy[k] * kx * ky;
                    }
                }
            }

            for (int k = 0; k < 3; k++)
            {
                result[k] /= k_sum;
            }

            return(inputImg.getRGB_fromB(result));
        }
Ejemplo n.º 11
0
        public void ball_distort(double height, string interp_method = "最近邻")
        {
            /*
             * 球形变换,将结果赋予resultImg
             * height: 球形变换的高度参数
             */
            resultImg = new myMat();
            double height_abs = System.Math.Abs(height);
            double m          = System.Math.Sqrt(inputImg.height * inputImg.height + inputImg.width * inputImg.width) / 2;
            double radius     = (height * height + m * m) / 2 / height_abs;

            myMat.myCoor mid_p = new myMat.myCoor(inputImg.height / 2, inputImg.width / 2);
            resultImg.init_bytes(inputImg.height, inputImg.width);
            for (int i = 0; i < inputImg.height; i++)
            {
                for (int j = 0; j < inputImg.width; j++)
                {
                    myMat.myCoor sourceCoor = ball_source_coor(new myMat.myCoor(i, j), mid_p, radius, direction: (int)(height / height_abs));
                    Color        c          = interp(sourceCoor, interp_method);
                    resultImg.set_rgb(c, new myMat.myCoor(i, j));
                }
            }
        }
Ejemplo n.º 12
0
        //切除黑边
        public void BlackCut_tran(string interp_method = "最近邻")
        {
            blackCut_distort = new Pic_distort();

            blackCut_distort.inputImg = new myMat();
            blackCut_distort.inputImg.getData_Mat(sourceFace_distort.resultImg);
            blackCut_distort.resultImg = new myMat();
            blackCut_distort.resultImg.init_bytes(blackCut_distort.inputImg.height, blackCut_distort.inputImg.width);

            /*Bitmap bm = blackCut_distort.inputImg.img2Bitmap();
             * Image<Bgr, byte> draw_img = new Image<Bgr, byte>(bm);
             * draw_img.Draw(new Cross2DF(new PointF((int)leftUp_point.j, (int)leftUp_point.i), 10, 10), new Bgr(0, 0, 255), 2);
             * draw_img.Draw(new Cross2DF(new PointF((int)leftDown_point.j, (int)leftDown_point.i), 10, 10), new Bgr(0, 0, 255), 2);
             *
             * CvInvoke.Imshow("a", draw_img);
             * CvInvoke.WaitKey();*/

            double turn_angle   = System.Math.Atan2((leftDown_point.j - leftUp_point.j), (leftDown_point.i - leftUp_point.i));
            double height_scale = myMat.myCoor.getDis(leftUp_point, leftDown_point) / blackCut_distort.resultImg.height;

            for (int i = 0; i < blackCut_distort.inputImg.height; i++)
            {
                for (int j = 0; j < blackCut_distort.inputImg.width; j++)
                {
                    if (i == blackCut_distort.inputImg.height - 3 && j == 0)
                    {
                        int a = 0;
                    }
                    myMat.myCoor sourceCoor = Turn_get_sourceCoor(i, j, turn_angle);
                    sourceCoor.i *= height_scale;
                    sourceCoor.j *= height_scale;
                    sourceCoor.i += (int)leftUp_point.i;
                    sourceCoor.j += (int)leftUp_point.j;
                    Color c = blackCut_distort.interp(sourceCoor, interp_method);
                    blackCut_distort.resultImg.set_rgb(c, new myMat.myCoor(i, j));
                }
            }

            /*Bitmap bm2 = blackCut_distort.resultImg.img2Bitmap();
             * Image<Bgr, byte> draw_img2 = new Image<Bgr, byte>(bm2);
             *
             * CvInvoke.Imshow("a", draw_img2);
             * CvInvoke.WaitKey();*/

            int min_y, max_y, max_x, min_x;

            blackCut_getIJ(out min_y, out max_y, out min_x, out max_x);

            int new_height = max_x - min_x + 1;
            int new_width  = max_y - min_y + 1;

            for (int i = 0; i < new_height; i++)
            {
                for (int j = 0; j < new_width; j++)
                {
                    int   i_cut        = min_x + i;
                    int   j_cut        = min_y + j;
                    Color source_color = blackCut_distort.resultImg.getRGB(new myMat.myCoor(i_cut, j_cut));
                    blackCut_distort.resultImg.set_rgb(source_color, new myMat.myCoor(i, j));
                }
            }
            blackCut_distort.resultImg.height = new_height;
            blackCut_distort.resultImg.width  = new_width;
        }