OpenCvSharp 学习笔记22-- 霍夫变换 -像素重映射

一,像素重映射介绍:

简单的说就是把输入图像中各像素按照一定的规则映射到另一张图像对应的位置上去,形成一张新的图像。
在这里插入图片描述
g ( x , y ) g(x,y) g(x,y) 是重映射之后的图像, h ( x , y ) h(x,y) h(x,y) 是功能函数,f 是源图像。

官方图例:
假设我们有一个图像 I I I :
h ( x , y ) = ( I . c o l s − x , y ) h(x,y)=(I.cols-x,y) h(x,y)=(I.colsx,y)
图像会在x轴上翻转:
在这里插入图片描述
上图右边的是源图像,左边的是重映射后的图像。相当于镜像了一副图像,左边的到右边,右边的到左边。

二,API:

Cv2.Remap() :

参数描述
InputArray src输入源图像
OutputArray dst输出图像
InputArray map1X轴映射表:具有CV_16SC2、CV_32FC1或CV_32FC2类型的(x,y)点或x值的第一个映射。
InputArray map2Y轴映射表:具有CV_16UC1、CV_32FC1或none类型的y值的第二个映射(如果map1是(x,y)点,则为空映射)。
InterpolationFlags interpolation = InterpolationFlags.Linear插值方法(可选择,线性,双线性,立方等)。这个函数不支持INTER_AREA方法。
BorderTypes borderMode = BorderTypes.Constant边缘处理方法
Scalar? borderValue = null边缘填充的颜色

三,代码:

 #region 像素重映射
        static int index = 0;
        private static void Remap(string path)
        {
            Mat src = new Mat(path, ImreadModes.AnyColor | ImreadModes.AnyDepth);
            Mat dst = new Mat(src.Size(), src.Type());

            Mat x = new Mat(src.Rows, src.Cols, MatType.CV_32FC1);
            Mat y = new Mat(src.Rows, src.Cols, MatType.CV_32FC1);
            new Window("Input", WindowMode.AutoSize, src);
            int key = 0;
            while (true)
            {
                key = Cv2.WaitKey(500);
                index = key % 4;
                if ((char)key == 27)
                {
                    break;
                }
                Console.WriteLine("{0}%{1}={2}", key, 4, index);
                Update_Remap(src, x, y);
                Cv2.Remap(src, dst, x, y, InterpolationFlags.Linear, BorderTypes.Constant, new Scalar(0, 0, 255));
                new Window("Output", WindowMode.AutoSize, dst);
            }

        }

        private static void Update_Remap(Mat src, Mat x, Mat y)
        {

            for (int row = 0; row < src.Rows; row++)
            {
                for (int col = 0; col < src.Cols; col++)
                {
                    switch (index)
                    {
                        case 0:
                            if (col > (src.Cols * 0.25) && col < (src.Cols * 0.75) && row > (src.Rows * 0.25) && row < (src.Rows * 0.75))
                            {
                                /*
                                 * 图像的 Cols 列 组成矩阵的宽度 对应 二维平面的x轴
                                 * 图像的 Rows 行 组成矩阵的高度 对应 二维平面的y轴
                                 * if 条件成立必定满足  
                                 *          src.Cols*0.75 <= col <= src.Cols*0.25
                                 *          src.Rows*0.75 <= row <= src.Rows*0.25
                                 * 则:
                                 *  (col - (src.Cols * 0.25)范围在 0 -- 0.5 之间
                                 *   若 (2 * (col - (src.Cols * 0.25)) 则:范围在 0 --1 之间 (原图像的大小)X轴
                                 *   (row - (src.Rows * 0.25))范围在 0 -- 0.5 之间
                                 *   若 (2 * (row - (src.Rows * 0.25)) 则:范围在 0 --1 之间 (原图像的大小)Y轴
                                 *   
                                 *   前面创建 x ,y 对象是的类型是 CV_32FC1 所以 赋值要用 float 类型
                                 */
                                float xVal = (float)(2 * (col - (src.Cols * 0.25)));
                                float yVal = (float)(2 * (row - (src.Rows * 0.25)));
                                x.Set<float>(row, col, xVal);
                                y.Set<float>(row, col, yVal);
                            }
                            else
                            {
                                x.Set<float>(row, col, 0);
                                y.Set<float>(row, col, 0);
                            }
                            break;
                        case 1:
                            x.Set<float>(row, col, (src.Cols - col - 1)); //左右映射  X 轴
                            y.Set<float>(row, col, row); //Y 轴不变
                            break;
                        case 2:
                            x.Set<float>(row, col, col); //X 轴
                            y.Set<float>(row, col, (src.Rows - row - 1)); //上下映射 Y轴
                            break;
                        case 3:
                            x.Set<float>(row, col, (src.Cols - col - 1)); //左右映射  X 轴
                            y.Set<float>(row, col, (src.Rows - row - 1));//上下映射 Y轴
                            break;
                    }
                }
            }
        }

选择输出图像窗口 按 1
在这里插入图片描述
按2

在这里插入图片描述

按 3:
在这里插入图片描述
按 4:
在这里插入图片描述

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值