常用的像素操作算法:Resize、Flip、RotateResizeFlipRotate总结

Resize

图像缩放是把原图像按照目标尺寸放大或者缩小,是图像处理的一种。

图像缩放有多种算法。最为简单的是最临近插值算法,它是根据原图像和目标图像的尺寸,计算缩放的比例,然后根据缩放比例计算目标像素所依据的原像素,过程中自然会产生小数,这时就采用四舍五入,取与这个点最相近的点。

除此之外,还有双线性插值算法。

双线性插值,又称为双线性内插。在数学上,双线性插值是有两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值。

其公式如下: f(i+u,j+v) =(1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1)

其中U和V表示浮点坐标的小数部分,显然离目标点距离越近的点的权重越大,这也正符合目标点的值与离他最近的点最接近这一事实。

cv4j的resize目前支持这两种算法。通过Resize类的源码,可以看到有两个常量

    public final static int NEAREST_INTEPOLATE = 1; // 最临近插值算法
    public final static int BILINE_INTEPOLATE = 2;     // 双线性插值算法

使用最临近插值算法,将原图缩小到0.75倍。

        CV4JImage cv4jImage = new CV4JImage(bitmap);
        ImageProcessor imageProcessor = cv4jImage.getProcessor();

        Resize resize = new Resize(0.75f);

        imageProcessor = resize.resize(imageProcessor,Resize.NEAREST_INTEPOLATE);

        if (imageProcessor!=null) {
            CV4JImage resultCV4JImage = new CV4JImage(imageProcessor.getWidth(), imageProcessor.getHeight(), imageProcessor.getPixels());
            result1.setImageBitmap(resultCV4JImage.getProcessor().getImage().toBitmap());
        }

使用双线性插值算法,将原图放大2倍。

        cv4jImage = new CV4JImage(bitmap);
        ImageProcessor imageProcessor2 = cv4jImage.getProcessor();

        resize = new Resize(2f);

        imageProcessor2 = resize.resize(imageProcessor,Resize.BILINE_INTEPOLATE);

        if (imageProcessor2!=null) {
            CV4JImage resultCV4JImage = new CV4JImage(imageProcessor2.getWidth(), imageProcessor2.getHeight(), imageProcessor2.getPixels());
            result2.setImageBitmap(resultCV4JImage.getProcessor().getImage().toBitmap());
        }

效果如下:

图像缩放.png

Flip

Flip是翻转的意思,也被称为镜像变换。又可以分为水平镜像和垂直镜像,水平镜像即将图像左半部分和右半部分以图像竖直中轴线为中心轴进行兑换,而竖直镜像则是将图像上半部分和下半部分以图像水平中轴线为中心轴进行兑换。

flip的算法很简单

    public final static int FLIP_VERTICAL = -1;
    public final static int FLIP_HORIZONTAL = 1;
    
    public static void flip(ImageProcessor processor, int option) {
        int width = processor.getWidth();
        int height = processor.getHeight();
        int ch = processor.getChannels();
        int index1 = 0;
        int index2 = 0;
        int total = width*height;
        byte[][] output = new byte[ch][total];
        for(int row=0; row<height; row++) {
            for(int col=0; col<width; col++) {
                index1 = row*width+col;
                if(option == FLIP_HORIZONTAL) {
                    index2 = row*width + width-col-1;
                } else if(option == FLIP_VERTICAL){
                    index2 = (height-row-1)*width + col;
                } else {
                    throw new CV4JException("invalid option : " + option);
                }
                for(int i=0; i<ch; i++) {
                    output[i][index2] = processor.toByte(i)[index1];
                }
            }
        }
        if(ch == 3) {
            ((ColorProcessor) processor).putRGB(output[0], output[1], output[2]);
        } else {
            ((ByteProcessor) processor).putGray(output[0]);
        }
    }

实现具体的左右翻转

        CV4JImage cv4jImage = new CV4JImage(bitmap);
        ImageProcessor imageProcessor = cv4jImage.getProcessor();

        Flip.flip(imageProcessor,Flip.FLIP_HORIZONTAL);

        if (imageProcessor!=null) {
            CV4JImage resultCV4JImage = new CV4JImage(imageProcessor.getWidth(), imageProcessor.getHeight(), imageProcessor.getPixels());
            result1.setImageBitmap(resultCV4JImage.getProcessor().getImage().toBitmap());
        }

实现具体的上下翻转

        cv4jImage = new CV4JImage(bitmap);
        ImageProcessor imageProcessor2 = cv4jImage.getProcessor();

        Flip.flip(imageProcessor2,Flip.FLIP_VERTICAL);

        if (imageProcessor2!=null) {
            CV4JImage resultCV4JImage = new CV4JImage(imageProcessor2.getWidth(), imageProcessor2.getHeight(), imageProcessor2.getPixels());
            result2.setImageBitmap(resultCV4JImage.getProcessor().getImage().toBitmap());
        }

效果如下:

图像翻转.png

Rotate

图像旋转是指图像以某一点为中心旋转一定的角度,形成一幅新的图像的过程。当然这个点通常就是图像的中心。既然是按照中心旋转,自然会有这样一个属性:旋转前和旋转后的点离中心的位置不变。

图像的旋转是图像几何变换的一种,旋转前后的图像的像素的RGB都是没有改变的,改变的只是每一个像素的所在位置。

cv4j提供两种旋转的算法:NormRotate和FastRotate

下面以NormRotate为例,使用起来很简单,旋转120度,背景为红色。

        CV4JImage cv4jImage = new CV4JImage(bitmap);
        ImageProcessor imageProcessor = cv4jImage.getProcessor();

        NormRotate normRotate = new NormRotate();
        imageProcessor = normRotate.rotate(imageProcessor,120, Scalar.rgb(255,0,0));

        if (imageProcessor!=null) {
            CV4JImage resultCV4JImage = new CV4JImage(imageProcessor.getWidth(), imageProcessor.getHeight(), imageProcessor.getPixels());
            result.setImageBitmap(resultCV4JImage.getProcessor().getImage().toBitmap());
        }

效果如下:

图像旋转.png

总结

cv4jgloomyfish和我一起开发的图像处理库,纯java实现,我们已经分离了一个Android版本和一个Java版本。

像素操作是 cv4j 的基本功能之一,本文介绍了三种常见的变换。我们可以通过图像的Resize、Flip、Rotate变换来丰富图片数据的多样性。

如果您想看该系列先前的文章可以访问下面的文集: http://www.jianshu.com/nb/10401400

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏机器学习算法工程师

机器学习实战——LBP特征提取

作者:张旭 编辑:栾志勇 零 全篇概述: LBP(Local Binary Pattern)算法 是一种描述图像特征像素点与各个像素点之间的灰度关系的局部特征的...

1K80
来自专栏贾志刚-OpenCV学堂

深度学习AI美颜系列----AI美发算法(美妆相机/天天P图染发特效)

给照片或者视频中的人物头发换颜色,这个技术已经在手机app诸如天天P图,美图秀秀等应用中使用,并获得了不少用户的青睐。如何给照片或者视频中的人物头发换发色?换发...

68350
来自专栏专知

【专知荟萃25】文字识别OCR知识资料全集(入门/进阶/论文/综述/代码/专家,附查看)

OCR文字,车牌,验证码识别 专知荟萃 入门学习 论文及代码 文字识别 文字检测 验证码破解 手写体识别 车牌识别 实战项目 视频 入门学习 端到端的OCR...

2.1K80
来自专栏专知

【论文推荐】最新六篇图像分割相关论文—控制、全卷积网络、子空间表示、多模态图像分割

【导读】专知内容组整理了最近六篇图像分割(Image Segmentation)相关文章,为大家进行介绍,欢迎查看! 1.Virtual-to-Real: Le...

46150
来自专栏一心无二用,本人只专注于基础图像算法的实现与优化。

基于Simple Image Statistics(简单图像统计,SIS)的图像二值化算法。

  这是个简单的算法,是全局二值算法的一种,算法执行速度快。     算法过程简单描述如下:  对于每一个像素,做如下处理        1、...

26260
来自专栏书山有路勤为径

特征类型和图像分割

我们最想检测的就是角点,因为角点是可重复性最高的特征,也就是说因为角点是可重复性最高的特征,给出关于同一景象的两张或以上图像 我们就能很轻易地识别出这类特征。 ...

15030
来自专栏图形学与OpenGL

模拟试题A

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wpxu08/article/detail...

58510
来自专栏AIUAI

Caffe2 - (三十) Detectron 之 modeling - 模型_heads

93870
来自专栏专知

【论文推荐】最新5篇图像描述生成(Image Caption)相关论文—情感、注意力机制、遥感图像、序列到序列、深度神经结构

【导读】专知内容组整理了最近五篇图像描述生成(Image Caption)相关文章,为大家进行介绍,欢迎查看! 1. Image Captioning at W...

72150
来自专栏天天P图攻城狮

终端图像处理系列 - OpenGL ES 2.0 - 3D基础(矩阵投影)

Overview 移动设备的屏幕是二维平面,要想把一个三维场景渲染在手机二维屏幕上,需要利用OpenGL中的矩阵投射,将三维空间中的点映射到二维平面上。三维矩阵...

616110

扫码关注云+社区

领取腾讯云代金券