c JPEG 1D DCT 优化二(AAN)

这两个图可能就是AAN 的数学模型

5800b8c697ce4accbc2ede90e8731caf.jpeg

 

b13cb6c027574fba9fbe7725f226143c.jpeg

优化DCT就是用代码实现矩阵9,10

9和10已经把64个系数缩小到一半32个了。光从这两图可看出,优化后乘法少了64-32+4=36个,加法少了64-32-8=24。估计优化时间可少百分之40左右。

实际编码640×480 的图片,程序执行时间缩短为0.13秒。

 

要想减少DCT时间就要尽量减少DCT函数的代码量,可以不用查表直接赋值。

最后一种优化就是象ffmpeg一样用汇编写DCT函数部分了。这种就搞不定了。

其实还有一个更笨的办法:因为这些cos系数是固定的,只要手算-128到127这255个数与这些系数相乘作为一个表,DCT就不用浮点乘法运算,这样可能又要少点时间。但这个表有点大。DCT就简化为只有查表加法两个动作了。

下一个目标,h264!

实现9,10 矩阵代码:

​
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define PI 3.1415926

int main(void){
	//cs:cos(PI*(2*n+1)*k/16)
	
	/*	double cs[64]={1,      1,     1,    1,    1,     1,     1,      1,
	0.98,  0.83, 0.56, 0.20, -0.20, -0.56,  -0.83, -0.98,
	0.92,  0.38, -0.38, -0.92, -0.92, -0.38, 0.38, 0.92 ,
	0.83,  -0.20, -0.98, -0.56, 0.56, 0.98,  0.20, -0.83,
	0.71,  -0.71, -0.71, 0.71,  0.71,  -0.71, -0.71,0.71,
	0.56,  -0.98, 0.20, 0.83,  -0.83, -0.20, 0.98, -0.56,
	0.38, -0.92,  0.92, -0.38, -0.38,  0.92, -0.92, 0.38,
	0.20,  -0.56, 0.83, -0.98, 0.98,   -0.83, 0.56,  -0.20
	};
	
	//--------------1D DCT-----------------------------------------
	int  DCT(double i[8],double o[8]){       //ID DCT  参数类型不能用unsigned char ,因为中间系数已超char取值范围
	double s=0.0;
	
	for(int k=0;k<8;k++){
	for(int n=0;n<8;n++){
	s=s+i[n]*cs[k*8+n];  //查cs表
	}
	
	if(k==0){
	s=s*(1.0/(2*sqrt(2)));
	}else{
	s=s*(1.0/2);
	}
	
	o[k]=s;
	s=0.0;
	}
	return 0;
	
	}*/
	
	double cs1[16]={1,      1,     1,    1, 
		0.92,  0.38, -0.38, -0.92,
		0.71,  -0.71, -0.71, 0.71,
		0.38, -0.92,  0.92, -0.38, 
		
	};
	double cs2[16]={
		0.98,  0.83, 0.56, 0.20, 
		0.83,  -0.20, -0.98, -0.56,
		0.56,  -0.98, 0.20, 0.83,  
		0.20,  -0.56, 0.83, -0.98, 
	};
	
	int  DCT(double i[8],double o[8]){       //采用AAN 方式
		double z0=i[0]+i[7];
		double  z1=i[0]-i[7];
		double z2=i[1]+i[6];
		double z3=i[1]-i[6];
		double z4=i[2]+i[5];
		double z5=i[2]-i[5];
		double z6=i[3]+i[4];
		double z7=i[3]-i[4];
		
		o[0]=(cs1[0]*z0+cs1[1]*z2+cs1[2]*z4+cs1[3]*z6)*(1.0/(2*sqrt(2)));
		o[1]=(cs2[0]*z1+cs2[1]*z3+cs2[2]*z5+cs2[3]*z7)*(1.0/2);
		
		o[2]=(cs1[4]*z0+cs1[5]*z2+cs1[6]*z4+cs1[7]*z6)*(1.0/2);
		o[3]=(cs2[4]*z1+cs2[5]*z3+cs2[6]*z5+cs2[7]*z7)*(1.0/2);
		
		o[4]=(cs1[8]*z0+cs1[9]*z2+cs1[10]*z4+cs1[11]*z6)*(1.0/2);
		o[5]=(cs2[8]*z1+cs2[9]*z3+cs2[10]*z5+cs2[11]*z7)*(1.0/2);
		
		o[6]=(cs1[12]*z0+cs1[13]*z2+cs1[14]*z4+cs1[15]*z6)*(1.0/2);
		o[7]=(cs2[12]*z1+cs2[13]*z3+cs2[14]*z5+cs2[15]*z7)*(1.0/2);
		
		return 0;
	}
	
	
//--------------------------------------------------------------------
	double i[64]={
		-76,-73,-67,-62,-58,-67,-64,-55,
		-65,-69,-73,-38,-19,-43,-59,-56,
		-66,-69,-60,-15,16,-24,-62,-55,
		-65,-70,-57,-6,26,-22,-58,-59,
		-61,-67,-60,-24,-2,-40,-60,-58,
		-49,-63,-68,-58,-51,-60,-70,-53,
		-43,-57,-64,-69,-73,-67,-63,-45,
		-41,-49,-59,-60,-63,-52,-50,-34
	};
	
//-------------8行分别1D DCT---------------------
	
	double w[64]={};      //中间8×8
	
	for(int a=0;a<64;a=a+8){
		double ls_o[8]={};
		double ls_i[8]={};
		memcpy(ls_i,&(i[a]),64);
		DCT(ls_i,ls_o);
		memcpy(&(w[a]),ls_o,64);
	}
	
//----------对中间8×8 列1D DCT-------------------------
	
	double zj[8][8]={};    //取中间w的8个8列
	int t=0;
	for(int a=0;a<8;a++){
		for(int b=0;b<8;b++){
			zj[t][b]=w[b*8+a];
		}
		t++;
	}
	
	double ll[64]={};      //现在的列是水平放置的,也就是列变成了行,要转为列
	
	for(int a=0;a<8;a++){    //对8列1D DCT
		double zz[8]={};
		DCT(zj[a],zz);
		memcpy(&(ll[8*a]),zz,64);
		
	}
	
	int k=0;
	double  out[64]={};          //2D DCT 系数
	for(int a=0;a<8;a++){
		for(int b=0;b<8;b++){
			out[8*b+a]=ll[k];
			k++;
		}
	}
	
	
//----------显示--------------------------------------------
	for(int a=0;a<8;a++){
		for(int b=0;b<8;b++){
			printf("%f ,",out[a*8+b]);
		}
		puts("");
		
	}
	
	return 0;
}

​

 

 

 

 

 

 

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/333959.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL窗口函数(MySQL Window Functions)

1、窗口函数基本概念 官网地址&#xff1a;https://dev.mysql.com/doc/refman/8.0/en/window-functions.html 窗口可以理解为 记录集合&#xff0c;窗口函数就是在满足某种条件的记录集合上执行的特殊函数。 即&#xff1a;每条记录都要在此窗口内执行函数。 静态窗口&#x…

多目标优化中常用的差分进化算法DE【2】

# 多目标优化中常用的进化算法 1、链接一 2、链接二 #后续继续补充多目标的差分进化算法MODE的应用 此链接介绍很详细&#xff0c;此处用来分享学习&#xff0c;后续有问题会继续进行补充。 如果你觉得不错&#xff0c;佛系随缘打赏&#xff0c;感谢&#xff0c;你的支持是…

「完美世界」石昊融合仙金化真龙,八九天功小成,借天时斩杀真神

Hello,小伙伴们&#xff0c;我是拾荒君。 国漫《完美世界》第146期超前爆料&#xff0c;据透露石昊从天人族手中意外夺得一件名为“仙金”的神秘宝物。这件宝物颇具灵性&#xff0c;令石昊十分好奇。而令人震惊的是&#xff0c;这仙金竟然能够承受齐道临的一击。齐道临透露&am…

HackTheBox - Medium - Linux - Health

Health Health 是一台中型 Linux 计算机&#xff0c;在主网页上存在 SSRF 漏洞&#xff0c;可利用该漏洞访问仅在 localhost 上可用的服务。更具体地说&#xff0c;Gogs 实例只能通过 localhost 访问&#xff0c;并且此特定版本容易受到 SQL 注入攻击。由于攻击者可以与 Gogs …

我在阿里巴巴是是这样做架构师的

阿里巴巴是杭州的标志性大型互联网公司&#xff0c;也是中国做电商最成功的企业&#xff0c;几乎所有玩电商的都是以阿里巴巴为权威机构&#xff0c;当然这个只是在国内是这样的&#xff0c;那么国外还是有很强的竞争对手的&#xff0c;比如亚马逊。 那么作为一名资深的架构师…

JavaScript DOM可以做什么?

1、通过id获取标签元素 DOM是文档对象模型&#xff0c;它提供了一些属性和方法来方便我们操作document对象&#xff0c;比如getElementById()方法可以通过某个标签元素的id来获取这个标签元素 // 用法 window.document.getElementById(id); // 例子 <!DOCTYPE html> &l…

C#MQTT编程07--MQTT服务器和客户端(wpf版)

1、前言 上篇完成了winform版的mqtt服务器和客户端&#xff0c;实现了订阅和发布&#xff0c;效果666&#xff0c;长这样 这节要做的wpf版&#xff0c;长这样&#xff0c;效果也是帅BBBB帅&#xff0c;wpf技术是cs程序软件的福音。 wpf的基础知识和案例项目可以看我的另一个专…

Zookeeper安装教程

系列文章目录 Zookeeper简介 文章目录 前言一、选择安装包二、使用wget下载并安装zookeeper 前言 Linux下Zookeeper安装步骤 一、选择安装包 Zookeeper下载地址&#xff1a;https://zookeeper.apache.org/releases.html 选择一个稳定版本即可&#xff0c;我这里选择的是3.7.2…

微服务-服务拆分和远程调用

任何分布式架构都离不开服务的拆分&#xff0c;微服务也是一样。 一、服务拆分原则 微服务拆分时的几个原则&#xff1a; 不同微服务&#xff0c;不要重复开发相同业务 微服务数据独立&#xff0c;不要访问其它微服务的数据库 微服务可以将自己的业务暴露为接口&#xff0c;…

C++ 数论相关题目(约数)

1、试除法求约数 主要还是可以成对的求约数进行优化&#xff0c;不然会超时。 时间复杂度根号n #include <iostream> #include <vector> #include <algorithm>using namespace std;int n;vector<int> solve(int a) {vector<int> res;for(int i…

系统性学习vue-vuex

系统性学习vue-vuex 理解vuexvuex工作原理搭建vuex环境案例Vuex的开发者工具使用getters配置项mapState与mapGettersmapActions和mapMutationsvuex模块化namespace 理解vuex 概念&#xff1a; 专门在Vue中实现集中式状态&#xff08;数据&#xff09;管理的一个Vue插件&#xf…

GIS复试Tips(特别是南师大)

注&#xff1a;本文仅个人观点&#xff0c;仅供参考 在这提前㊗️24年考南师大GISer成功上岸&#xff01; 当然&#xff0c;考研是个考试&#xff0c;总有人顺利上岸&#xff0c;稳上岸或逆袭上岸&#xff0c;但可能也有人被刷&#xff0c;这是常态。 所以&#xff0c;㊗️你…

RHCE作业

网站需求&#xff1a; 题目一&#xff1a; 基于域名[www.openlab.com](http://www.openlab.com)可以访问网站内容为 welcome to openlab!!! 配置&#xff1a; 1&#xff0c;关闭防护墙&#xff0c;关闭selinux [rootnodel ~]# systemctl stop firewalld [rootnodel ~]# se…

TEE2024大湾区进出口贸易博览会

TEE2024大湾区进出口贸易博览会 INTE 2024RNATIONAL TRADE E-COMMERCE EXPO 时间&#xff1a;2024年08月11--13日 地点&#xff1a;深圳福田会展中心 联合主办&#xff1a; 深圳市电子商务协会 深圳市跨境电子商务行业发展促进会 广东进出口商会 广东省国牌出海电子商务…

Qt/QML编程之路:OpenGL的示例(39)

Qt编程之后,会发现有版本问题,有时候一个示例不同的版本下可能会跑不同,有些Qt5跑不同Qt6已经完善,可以跑通。 我就看到有个关于OpenGL的示例: 这个示例是演示怎么基于OpenGL编程的,但是调试时却发现glViewXXX等gl打头的函数说找不到reference,或者什么link不上之类的错…

ffmpeg 常用命令行详解

概述 ffmpeg 是一个命令行音视频后期处理软件 1. 裁剪命令 参数说明 -i 文件&#xff0c;orgin.mp3 为待处理源文件-ss 裁剪时间&#xff0c;后跟裁剪开始时间&#xff0c;或者开始的秒数-t 裁剪时间output.mp3 为处理结果文件 ffmpeg -i organ.mp3 -ss 00:00:xx -t 120 o…

轻松一刻 浅休息下哈

yum -y install epel-release yum install -y linux_logo cal 此命令以日历表的方式显示日期 curl http://wttr.in 此网站进行在屏幕上面显示天气情况

mybatis-plus批量保存异常及效率优化

最近基于自己公司内部服务维护&#xff0c;发现其中调度中心近期出现不少错误日志&#xff0c;但是该任务却是正常执行&#xff0c;生成的报表数据也是正常的&#xff0c;所以很多天没有发现问题 这就匪夷所思了&#xff0c; 经仔细排查发现&#xff0c;是触发了feign超时hyst…

Js-WebAPIs-事件(二)

事件监听&#xff08;绑定&#xff09; 什么是事件&#xff1f; 事件是在编程时系统内发生的动作或者发生的事情 比如用户在网页上单击一个按钮 什么是事件监听&#xff1f; 就是让程序检测是否有事件产生&#xff0c;一旦有事件触发&#xff0c;就立即调用一个函数做出响…

1.19(232.用栈实现队列)

1.19(232.用栈实现队列) 在push数据的时候&#xff0c;只要数据放进输入栈就好&#xff0c;但在pop的时候&#xff0c;操作就复杂一些&#xff0c;输出栈如果为空&#xff0c;就把进栈数据全部导入进来&#xff08;注意是全部导入&#xff09;&#xff0c;再从出栈弹出数据&a…
最新文章