博文

[置顶] JPEG2000压缩技术(2008-04-19 14:41:00)

摘要:
JPEG2000压缩技术  http://i.cn.yahoo.com/jielin/blog/p_28/ 一、引言 传统图像编码采用离散余弦变换(DCT)技术,可以较好地去除图像信息的统计冗余,具有良好的实时性和块操作与运动估计的匹配性。目前该技术日臻成熟,形成了JPEG、MPEG等国际标准。但是由于DCT变换过程采用分块技术,在高压缩比条件下容易导致方块效应,严重影响主观质量。而且DCT不适合带宽较宽(拥有较多边缘轮廓信息)的图像信号。于是人们将目光转向小波变换。 传统的卷积小波变换是一种不受带宽约束的图像处理方法,支持多分辨率、多码率传输方案,而且不对图像进行分块,避免了DCT变换的方块效应。但是,采用卷积运算方法,过程复杂,运算量大,实时性不好,不利于硬件的实现。而基于JPEG2000标准推荐的提升小波变换,采用9/7、5 /3滤波器组对分解的图像进行提升运算,不但继承了传统小波变换的优点,而且实时性好、运算简单、易于硬件实现。 JPEG2000具有以下主要特点: (1)    良好的低比特率压缩性能这是JPEG2000最主要的特征。 目前的JPEG标准,对于细节分量多的灰度图像,当码率低于0.25bpp(0.25bit/piexl)时,视觉失真大。为克服这一点,要求JPEG2000在低比特率下有良好的率失真性能,以适应网络、移动通信等有限带宽的应用需要。 (2)连续色调和二值图像压缩 目前的JPEG标准对于自然图像具有较好的压缩性能,但是当用于计算机图形和二值文本的压缩时,性能变差,不适用于复合文本压缩。为了改进这一点,JPEG2000在统一系统中采用相似的方法,能够对自然图像、复合文本、医学图像、计算机图形等具有不同特征、不同类型的图像进行压缩。 (3)有损和无损压缩 对于目前的JPEG标准,在同一个压缩码流中不能同时提供有损和无损两种压缩,而在JPEG2000系统中,通过选择参数,能够对图像进行有损和无损两种压缩,可满足图像质量要求很高的医学图像、图像库等方面的处理需要。 (4) 按照像素精度或者分辨率进行累进式传输 累进式图像传输允许图像按照所需的分辨率或像素精度进行重构,用户根据需要,对图像传输进行控制,在获得所需的图像分辨率或质量要求后,便可终止解码,而不必接收整个图像压缩码......

阅读全文(5741) | 评论:15 | 复制链接

运输法虚重载(2008-11-03 21:47:00)

摘要:你这儿是没有办法把<<申明为virtual,因为作为成员函数   
  <<只能是ostream的member。   
  不过换一种方法还是可以的   
  大致如下哈:   
    
  class   FtpMessage   {   
  protected:   
      virtual   void   ToString(ostream   &os)   =   0;   
  public:   
      ...   
      friend   ostream&   operator   <<(ostream&   os,   FtpMessage   &   msg);   
  };   
    
  ostream&   operator   <<(ostream&   os,   FtpMessage   &   msg)   
  {   
    &nb......

阅读全文(3138) | 评论:1 | 复制链接

select函数详解及应用(2008-10-31 21:26:00)

摘要:Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如connect、 accept、recv或recvfrom这样的阻塞程序(所谓阻塞方式block,顾名思义,就是进程或是线程执行到这些函数时必须等待某个事件的发生,如果事件没有发生,进程或线程就被阻塞,函数不能立即返回)。可是使用Select就可以完成非阻塞(所谓非阻塞方式non-block,就是进程或线程执行此函数时不必非要等待事件的发生,一旦执行肯定返回,以返回值的不同来反映函数的执行情况,如果事件发生则与阻塞方式相同,若事件没有发生则返回一个代码来告知事件未发生,而进程或线程继续执行,所以效率较高)方式工作的程序,它能够监视我们需要监视的文件描述符的变化情况——读写或是异常。下面详细介绍一下!

Select的函数格式(我所说的是Unix系统下的伯克利socket编程,和windows下的有区别,一会儿说明):

int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);

先说明两个结构体:

第一,struct fd_set可以理解为一个集合,这个集合中存放的是文件描述符(file descriptor),即文件句柄,这可以是我们所说的普通意义的文件,当然Unix下任何设备、管道、FIFO等都是文件形式,全部包括在内,所以毫无疑问一个socket就是一个文件,socket句柄就是一个文件描述符。fd_set集合可以通过一些宏由人为来操作,比如清空集合 FD_ZERO(fd_set *),将一个给定的文件描述符加入集合之中FD_SET(int ,fd_set *),将一个给定的文件描述符从集合中删除FD_CLR(int ,fd_set*),检查集合中指定的文件描述符是否可以读写FD_ISSET(int ,fd_set* )。一会儿举例说明。

第二,struct timeval是一个大家常用的结构,用来代表时间值,有两个成员,一个是秒数,另一个是毫秒数。

具体解释select的参数:

int maxfdp是一个整......

阅读全文(6036) | 评论:1 | 复制链接

利用结构体返回多个函数值(2008-10-24 23:53:00)

摘要:#include <iostream.h>
#include <malloc.h>
#include <string.h>

typedef struct student
{
    char name[10];
    int age;
}Student;

Student* fun1()
{
    Student* ps = new Student;
    strcpy(ps->name, "zhong");
    ps->age  = 0x100;
    return ps;
}

void main()
{
    Student* ps=fun1();  
    cout<<"name:"<<ps->name<<"\t"<<"age:"<<hex<<(*ps).age<<endl;
    delete ps;
}
一般的函数只能由一个返回值
如何同时返回 name 和age 呢?
我们可以将其封装到一个结构体中,这样就可以通过结构体的方式同时返回这两个参数

注意:每次使用了fun1后,一定要释放其内部声请的内存空间
比如本程序中的 delete ps; ,否则将造成内存泄漏

......

阅读全文(2876) | 评论:0 | 复制链接

DLL(动态链接库)专题(2008-10-21 18:54:00)

摘要:(0)   Windows API中所有的函数都包含在dll中,其中有3个最重要的DLL。       (1)   Kernel32.dll       它包含那些用于管理内存、进程和线程的函数,例如CreateThread函数;       (2)   User32.dll      它包含那些用于执行用户界面任务(如窗口的创建和消息的传送)的函数,例如CreateWindow函数;       (3)   GDI32.dll      它包含那些用于画图和显示文本的函数。   1.      静态库和动态库 (1)   静态库          函数和数据被编译进一个二进制文件(通常扩展名为.LIB)。在使用静态库的情况下,在编译链接可执行文件时,链接器从库中复制这些函数和数据并把它们和应用程序的其他模块组合起来创建最终的可执行文件(.Exe文件).当发布产品时,只需要发布这个可执行文件,并不需要发布被使用的静态库。 (2)   动态库       在使用动态库的时候,往往提供两个文件:一个引入库(.lib)文件和一个DLL(.dll)文件。虽然引入库的后缀名也是”lib”,但是动态库的引入库文件和静态库文件有着本质上的区别,对一个DLL来说,其引入库文件(.lib)包含该DLL导出的函数和变量的符号名,而.dll文件包含该DLL实际的函数和数据。在使用动态库的情况下,在编译链接可执行文件时,只需要链接该DLL的引入库文件,该DLL中的函数代码和数据并不复制到可执行文件中,直到可执行程序运行时,才去加载所需的DLL,将该DLL映射......

阅读全文(3122) | 评论:1 | 复制链接

内存空间操作(2008-10-10 17:53:00)

摘要:一个new肯定只需要写一个delete:
int (*arr)[10] = new int[20][10];
//use it...
delete []arr;
或者:
int **arr2 = new int*[20];
for (int i = 0; i < 20; ++i) arr2[i] = new int[10];
//use it...
for (int i = 0; i < 20; ++i) delete arr2[i];
delete arr2;

......

阅读全文(2142) | 评论:1 | 复制链接

函数可以独立使用的特例(2008-10-01 20:14:00)

摘要:如下代码:
const static LPCTSTR g_szIPCCustomMsg =
    _T("{34F673E2-878F-11D5-B98A-00B0D07B8C7C}");
const static UINT g_wmScanPassword =    RegisterWindowMessage(g_szIPCCustomMsg);
函数在函数体外定义是合法的。

解释: 静态对象和全局对象的初始化是在main函数执行之前进行的. 初始化(包括构造, 析构)对象的时候可以调用函数, 并且也就这一种情况可以在主函数外部调用函数.
MFC里面不是有个全局变量theApp吗, 也是这样子.
另外,C语言只有规定过不能在函数体内定义函数,没有规定在函数体外不能调用函数,既然没有限制就是允许的!

......

阅读全文(1994) | 评论:1 | 复制链接

介绍Windows的窗口、消息、子类化和超类化(2008-09-21 14:15:00)

摘要:

眼见为实(2):介绍Windows的窗口、消息、子类化和超类化 介绍Windows的窗口、消息、子类化和超类化 这篇文章本来只是想介绍一下子类化和超类化这两个比较“生僻”的名词。为了叙述的完整性而讨论了Windows的窗口和消息,也简要讨论了进程和线程。子类化(Subclassing)和超类化(Superclassing)是伴随Windows窗口机制而产生的两个复用代码的方法。不要把“子类化、超类化”与面向对象语言中的派生类、基类混淆起来。“子类化、超类化”中的“类”是指Windows的窗口类。 0 运行程序 希望读者在阅读本节前先看看"谈谈Windows程序中的字符编码"开头的第0节和附录0。第0节介绍了Windows系统的几个重要模块。附录0概述了Windows的启动过程,从上电到启动Explorer.exe。本节介绍的是运行程序时发生的事情。 0.1 程序的启动 当我们通过Explorer.exe运行一个程序时,Explorer.exe会调用CreateProcess函数请求系统为这个程序创建进程。当然,其它程序也可以调用CreateProcess函数创建进程。 系统在为进程分配内部资源,建立独立的地址空间后,会为进程创建一个主线程。我们可以把进程看作单位,把线程看作员工。进程拥有资源,但真正在 CPU上运行和调度的是线程。系统以挂起状态创建主线程,即主线程创建好,不会立即运行,而是等待系统调度。系统向Win32子系统的管理员 csrss.exe登记新创建的进程和线程。登记结束后,系统通知挂起的主线程可以运行,新程序才开始运行。 这时,在创建进程中CreateProcess函数返回;在被创建进程中,主线程在完成最后的初始化后进入程序的入口函数(Entry-point)。创建进程与被创建进程在各自的地址空间独立运行。这时,即使我们结束创建进程,也不会影响被创建进程。 0.2 程序的执行 可执行文件(PE文件)的文件头结构包含入口函数的地址。入口函数一般是Windows在运行时库中提供的,我们在编译时可以根据程序类型设定。在VC中编译、运行程序的小知识点讨论了Entry-point,读者可以参考。 入口函数前的过程可以被看作程序的装载过程。在装载时,系统已经做过全局和静态变量(在编译时可以确定地址)的初始化,有初......

阅读全文(4004) | 评论:0 | 复制链接

强制CPU开始新的周期的方法(2008-09-18 01:02:00)

摘要:#include <afx.h>
#include <stdio.h>

void GetCylc( unsigned int *lowPart, unsigned int *highPart )
{
    __asm {
        cpuid         // 强制CPU开始新的周期
        mov ecx, lowPart;
        mov ebx, highPart;
        rdtsc
        mov [ecx], eax;
        mov [ebx], edx;
    }
}

unsigned int lowPart1, lowPart2, highPart;

int main()
{
    char *s1 = "2o3i4jiojrewjeroiksopf";

    GetCylc( &lowPart1, &highPart );

    for(int i1=0;s1[i1]!=0;i1++)
        printf("%c",s1[i1]);
    printf("\n");

    CString s2 = "2o3i4jiojrewj......

阅读全文(2338) | 评论:0 | 复制链接

模式对话框(2008-09-17 19:10:00)

摘要:模式对话框
作者:冯明德 一、概述

对话框是一种特殊的窗口,它依据对话框模板资源而建立。
它与一般的窗口有些不同,很多过程由系统完成了,虽然用户还是要提供一个消息处理函数,但在此消息处理函数中,不需要将不关心的消息交由缺省消息处理函数。
实际上,调用缺省处理的过程又系统完成。 二、对话框消息处理函数

对话框也需要用户提供一个消息处理函数,但这个处理函数没有普通窗口的消息处理函数"权利大"。
对话框是一种系统定义的“窗口类”,它已经定义好了对应的消息处理函数。客户所作的消息处理函数,并不是直接与窗口连接,而是对对话框消息处理函数的一种补充,或者说“嵌入”。
因此,对话框处理函数不需要调用“缺省消息处理函数”。
当有消息被处理时,返回TRUE,没有消息需要处理时,返回FALSE,此时退出用户消息处理函数后,系统会去调缺省消息处理函数。 //对话框消息处理函数
//返回值类型为BOOL,与普通窗口处理函数不同。
BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{

switch (message)
{
case WM_INITDIALOG :
return TRUE ; //返回真,表示消息被处理了。

case WM_COMMAND :
switch (LOWORD (wParam))
{
case IDOK :
case IDCANCEL :
EndDialog (hDlg, 0) ; //使用EndDialog关闭对话框
return TRUE ;......

阅读全文(2009) | 评论:0 | 复制链接