美文网首页
几种简单的图像数据处理操作

几种简单的图像数据处理操作

作者: 窝窝蜗牛 | 来源:发表于2020-11-09 09:53 被阅读0次

前言

图像数据处理由于处理繁琐,数据量大,为了不占用cpu资源,一般由硬件模块处理,或者由GPU做处理。但是,对于一些简单的处理操作,我们还是有必要学习一下,因为有些简单场景没有必要调用硬件资源。以下操作虽然简单,但是我也调试了千万遍,才知道“纸上得来终觉浅,绝知此事要躬行”。

一、RGB的flip操作

LOCAL void _rgb_flip(uint16 *addr,int width,int height)
{   
    uint8 i = 0, j = 0;
    uint16 tmp_data = 0;
    for(i = 0;i < height;i++)
    {
        for(j = 0;j < width / 2;j++)
        {
            tmp_data = *(addr + j);
            *(addr + j) = *(addr + width - j - 1);
            *(addr + width - j - 1) = tmp_data;
        }
        addr += width;
    }   
}

rgb的存储格式是一个像素点对应一个数据存储,例如,RGB565的存储格式如下,所以一个像素点占俩字节,该算法也只适用565格式,不适用888格式


rgb565存储格式

二、YUV的填充操作

void _ISP_YUV420pFillBlack(ISP_ADDRESS_T *src, ISP_ADDRESS_T *dst,
                                       uint32 src_w, uint32 src_h,     uint32 dst_w, uint32 dst_h)
{
       uint32 s_y = src->yaddr, s_u = src->uaddr;
       uint32 d_y = dst->yaddr, d_u = dst->uaddr;
       uint8 y_value = 0, u_value = 128; //black
       if (dst_w > src_w && dst_h == src_h && (dst_w - src_w) % 4 == 0) {
               ISPSRV_LOGI("Fill in width");
               uint32 offset = (dst_w - src_w) >> 1;
               uint32 offset_ = dst_w - src_w - offset;
               for (int i = 0; i < dst_h; i++){
                       SCI_MEMSET((void *)d_y, y_value, offset);
                       d_y += offset;
                       SCI_MEMCPY((void *)d_y, s_y, src_w);
                       d_y += src_w, s_y += src_w;
                       SCI_MEMSET((void *)d_y, y_value, offset_);
                       d_y += offset_;

                       SCI_MEMSET((void *)d_u, u_value, offset >> 1);
                       d_u +=  offset >> 1;
                       SCI_MEMCPY((void *)d_u, s_u, src_w>>1);
                       d_u += src_w>>1, s_u += src_w>>1;
                       SCI_MEMSET((void *)d_u, u_value, offset_ >> 1);
                       d_u += offset_ >> 1;
               }
       } else if (dst_w == src_w && dst_h > src_h && (dst_h - src_h) % 4 == 0) {
               ISPSRV_LOGI("Fill in height");
               uint32 offset = (dst_h - src_h)>>1;
               uint32 offset_ = dst_h - src_h - offset;
               SCI_MEMSET((void *)d_y, y_value, offset * dst_w);
               d_y += offset * dst_w;
               SCI_MEMCPY((void *)d_y, s_y, src_w * src_h);
               d_y += dst_w * src_h;
               SCI_MEMSET((void *)d_y, y_value, offset_ * dst_w);
               d_y += offset_ * dst_w;

               SCI_MEMSET((void *)d_u, u_value, (offset * src_w) >>1);
               d_u += (offset * src_w) >>1;
               SCI_MEMCPY((void *)d_u, s_u, (src_w * src_h) >> 1);
               d_u += (src_w * src_h) >> 1;
               SCI_MEMSET((void *)d_u, u_value, (offset_ * src_w)>>1);
               d_u += (offset_ * src_w)>>1;
       } else {
               ISPSRV_LOGE("Size error !!!");
       }
}

该填充操作上半部分是未经过验证的,应该还存在问题,贴上去只为了凑点字数,看Fill in height即可
三、YUV的裁剪操作

void _ISP_YUV420pCutBlack(ISP_ADDRESS_T *src, ISP_ADDRESS_T *dst,
                                       uint32 src_w, uint32 src_h,     uint32 dst_w, uint32 dst_h)
{
       uint32 s_y = src->yaddr, s_u = src->uaddr;
       uint32 d_y = dst->yaddr, d_u = dst->uaddr;
       uint8 y_value = 0,u_value = 128;
       uint32 width = 0,height = 0;

       ISPSRV_LOGI("cut in width");
       uint32 offset = (src_w - dst_w)>>1;
       uint32 offset_ = src_w - dst_w - offset;
       s_y += offset;
       for(height = 0;height < dst_h;height++)
       {
            SCI_MEMCPY(d_y,s_y,dst_w);
            d_y += dst_w;
            s_y += src_w;
       }

       s_u += offset;
       for(height = 0;height < (dst_h >> 1);height++)
       {
            SCI_MEMCPY(d_u,s_u,dst_w);
            d_u += dst_w;
            s_u += src_w;
       }
}

针对YUV的填充和裁剪,最重要的就是要搞清楚YUV的数据存储格式,以上算法也是针对YUV420格式的


yuv420存储格式

之前参考别人代码,纳闷为什么只对y和u地址操作,而不做v地址操作,仔细一看会发现做u地址处理时已经把v数据也处理了。

相关文章

  • 几种简单的图像数据处理操作

    前言 图像数据处理由于处理繁琐,数据量大,为了不占用cpu资源,一般由硬件模块处理,或者由GPU做处理。但是,对于...

  • 图像的简单操作

    1. 输入/输出 Mat imread(const string& filename, int flags=1 )...

  • opencv在android平台下的开发【4】-图像滤波详解

    前言 在上一篇opencv-android-图像平滑处理文章中,简单介绍了几种图像平滑,也就是图像模糊的方法,使用...

  • Morphology -形态学操作

    前言 简单的来讲,形态学操作是基于形状的图像处理操作,通过将结构元素作用于输入图像来输出图像。 对图像形态学运算,...

  • imgproce腐蚀膨胀

    形态学操作简单来讲,形态学操作就是基于形状的一系列图像处理操作。通过将 结构元素 作用于输入图像来产生输出图像。 ...

  • tensorflow图像识别

    TensorFlow学习笔记(五)图像数据处理

  • opencv形态学转换

    原理 形态学操作是根据图像形状进行的简单操作。一般情况下对二值化图像进行的操作。需要输入两个参数,一个是原始图像,...

  • 关于MATLAB图像处理基础操作的记录

    一、图像的几何变换 1、图像的平移操作 2、图像的缩放操作 3、图像的旋转操作 4、图像的镜像操作 5、图像的错切...

  • OpenCV图像处理(七)图像滤波(2)

    1、形态学滤波 简单来说,形态学操作就是基于形状的一系列图像处理操作,最基本的形态学操作:膨胀、腐蚀。在图像处理中...

  • 几种复杂的PS抠图方法

    昨天介绍的几种方法抠图方法比较简单,只适用于简单的图像,那今天我们就来说一下几种复杂的PS抠图方法。 1、通道工具...

网友评论

      本文标题:几种简单的图像数据处理操作

      本文链接:https://www.haomeiwen.com/subject/xtxlbktx.html