JPEG图像压缩探索_zigzag扫描(原创)

续:《DCT变换的应用》 JPEG图像压缩探索_DCT变换的应用_jpeg dct-CSDN博客

在DCT图像变换完成后,需要把数据从高频到低频频域强度信号进行筛选等操作,为了方便算法进行操作,最好转化为一个一维的数据,而如果每一行都从左到右写入到一维数据表中,会导致高频和低频频域信号混杂在整个表不同的部位,不方便进行霍夫曼编码等操作。

因此,zigzag扫描算法就派上用场了,也就是按照图上顺序,从左上到右下写成一维数据。

另外,它还有一个额外的好处,就是以此方式把二维数据转换为一维数据后,并不需要知道原来二维数据的边长,一维数据可以以同样的规则重新填充为降维前的大小。

要顺利实现一个算法,要先清晰描述问题和现象,才方便找到规律,然后用程序语言描述。顺便也作为自己的一种推理能力训练。

分析图上规律,我认为可以分为两个部分进行数据写入:

1、图像分为两个部分,以包含最左下到最右上的对角线的部分为左三角形,右下部分则为右三角形:

2、左三角形部分写入规律,除(0,0)外,x方向游标x∈(1, 3, 5,7……)都是从当前点往左下移动,也就是x--(x>=0),y++;y方向游标y∈(2, 4, 6……)则是从当前点往右上,即x++,y--(y>=0)

3、右三角形部分写入规律,x方向游标x∈(1, 3, 5,7……)都是从当前点往右上移动,也就是x++(x<8),y--;右侧y方向游标y∈(2, 4, 6……)则是从当前点往左下,即x--,y++(y<8)

规律总结完毕,检查无漏,开始编写代码:


package com.cjztest.aboutJPEG;

public class Ziggan {

    public static void main(String[] args) {
        int mGrayPixels[] = {
                80,60,34,10,5,1,94,0,
                56,30,5,4,1,86,0,0,
                23,6,3,1,80,0,0,0,
                15,2,1,75,0,0,0,0,
                1,1,75,0,0,0,0,0,
                1,0,0,0,0,0,0,0,
                0,0,0,0,0,0,0,0,
                0,0,0,0,0,0,0,0
                };
        /* 
         * 左三角形部分:
         * 设向左下方前进为正方向,x轴起始点,1,3,5,7
         * 右上为正方向:y起始点:2,4,6
         * */    
        int matrixLen = 8;
        //先塞入第一个数
        int result[] = new int[matrixLen * matrixLen];
        result[0] = mGrayPixels[0];
        int resultOffset = 1;
        //开始遍历
        for (int offset = 1; offset < matrixLen; offset ++) {
            if (offset % 2 != 0) { //x起点
                for (int x = offset, y = 0; x >= 0; x--, y++) {
                    result[resultOffset++] = mGrayPixels[x + y * matrixLen];
                }
            } else { //y起点
                for (int y = offset, x = 0; y >= 0; y--, x++) {
                    result[resultOffset++] = mGrayPixels[x + y * matrixLen];
                }
            }
        }
        /*右三角形部分:
         * */
        for (int offset = 1; offset < matrixLen; offset ++) {
            if (offset % 2 != 0) { //x起点
                for (int x = offset, y = 7; x < matrixLen; x++, y--) {
                    result[resultOffset++] = mGrayPixels[x + y * matrixLen];
                }
            } else  { //y起点
                for (int y = offset, x = 7; y < matrixLen; y++, x--) {
                    result[resultOffset++] = mGrayPixels[x + y * matrixLen];
                }
            }
        }
        //读取结果
        for (int i = 0; i < matrixLen * matrixLen; i++) {
            System.out.print(result[i] + ", ");
            if ((i + 1) % matrixLen == 0) {
                System.out.println();
            }
        }
        
    }

}


运行结果:

80, 60, 56, 23, 30, 34, 10, 5,

6, 15, 1, 2, 3, 4, 5, 1,

1, 1, 1, 1, 1, 0, 0, 75,

75, 80, 86, 94, 0, 0, 0, 0,

0, 0, 0, 0, 0, 0, 0, 0,

0, 0, 0, 0, 0, 0, 0, 0,

0, 0, 0, 0, 0, 0, 0, 0,

0, 0, 0, 0, 0, 0, 0, 0,

源码:

src/com/cjztest/aboutJPEG/Ziggan.java · lvlv/JavaPractice - 码云 - 开源中国 (gitee.com)

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Zigzag扫描是一种在图像或视频编码中常用的扫描方式,通过这种方式可以将图像或视频中的像素按照一定的规律顺序排布。在Verilog中,可以使用循环结构和条件判断语句来实现Zigzag扫描。 具体实现步骤如下: 1. 首先,我们需要定义一个二维数组来表示图像或视频的像素矩阵。假设我们的像素矩阵是一个8x8的方阵,即有64个像素点。 2. 接下来,我们可以使用一个双重循环来遍历像素矩阵的每一个像素点。外层循环控制行数,内层循环控制列数。 3. 在内层循环中,我们使用一些条件判断语句来确定当前遍历的像素点的位置,并将其按照Zigzag扫描的规则进行排列。具体规则如下: a. 在第一行和最后一列的像素点,每个像素点只有一个方向可选,只需将当前像素点的行和列作为输出地址。 b. 在最后一行和第一列的像素点,每个像素点只有一个方向可选,只需将当前像素点的行和列作为输出地址。 c. 在剩余的像素点中,我们可以使用一个变量来控制输出地址的方向。当遍历到右上方时,行减一,列加一;当遍历到左下方时,行加一,列减一。 4. 最后,我们可以将每个像素点的行和列作为输出地址写入输出信号中,从而实现了Zigzag扫描。 通过上述步骤的Verilog实现,我们可以将图像或视频中的像素按照Zigzag扫描的规则进行排列,从而方便地进行后续的编码处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值