CvCreateImage函数说明

本文介绍了OpenCV中的关键函数,包括图像创建、色彩空间转换、直方图均衡化等,详细解析了CvCreateImage、cvCvtColor及cvEqualizeHist等功能及应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CvCreateImage函数说明

cvCreateImage是openCV中的一个函数。OpenCV是Intel公司支持的开源计算机视觉库。
  cvCreateImage:
  创建头并分配数据
  IplImage* cvCreateImage( CvSize size, int depth, int channels );
  参数说明:
  size 图像宽、高.
  depth 图像元素的位深度,可以是下面的其中之一:
  IPL_DEPTH_8U - 无符号8位整型
  IPL_DEPTH_8S - 有符号8位整型
  IPL_DEPTH_16U - 无符号16位整型
  IPL_DEPTH_16S - 有符号16位整型
  IPL_DEPTH_32S - 有符号32位整型
  IPL_DEPTH_32F - 单精度浮点数
  IPL_DEPTH_64F - 双精度浮点数
  channels:
  每个元素(像素)通道号.可以是 1, 2, 3 或 4.通道是交叉存取的,例如通常的彩色图像数据排列是:b0 g0 r0 b1 g1 r1 ... 虽然通常 IPL 图象格式可以存贮非交叉存取的图像,并且一些OpenCV 也能处理他, 但是 这个函数只能创建交叉存取图像.
  函数 cvCreateImage 创建头并分配数据,这个函数是下列的缩写型式:
  header = cvCreateImageHeader(size,depth,channels);

  cvCreateData(header);

注:

CvSize
矩形框大小,以像素为精度

typedef struct CvSize
{
int width;
int height;
}
CvSize;

inline CvSize cvSize( int width, int height );

 

CvRound函数:

openCv中的一个函数:

int cvRound (double value)

对一个double型的数进行四舍五入,并返回一个整型数!

附加:

函数 cvRound, cvFloor, cvCeil 用一种舍入方法将输入浮点数转换成整数。 cvRound 返回和参数最接近的整数值。 cvFloor 返回不大于参数的最大整数值。cvCeil 返回不小于参数的最小整数值。在某些体系结构中该函数 工作起来比标准 C 操作起来还要快。

 

注意下面的编程技巧:

typedef union Cv32suf
{
    int i;
    unsigned u;
    float f;
}
Cv32suf;

 

CV_INLINE  int  cvFloor( double value )
{
#if CV_SSE2  
    __m128d t = _mm_load_sd( &value );
    int i = _mm_cvtsd_si32(t);
    return i - _mm_movemask_pd(_mm_cmplt_sd(t,_mm_cvtsi32_sd(t,i)));
#else
    int temp = cvRound(value);
    Cv32suf diff;
    diff.f = (float)(value - temp);
    return temp - (diff.i < 0);
#endif
}


CV_INLINE  int  cvCeil( double value )
{
#if CV_SSE2
    __m128d t = _mm_load_sd( &value );
    int i = _mm_cvtsd_si32(t);
    return i + _mm_movemask_pd(_mm_cmplt_sd(_mm_cvtsi32_sd(t,i),t));
#else
    int temp = cvRound(value);
    Cv32suf diff;
    diff.f = (float)(temp - value);
    return temp + (diff.i < 0);
#endif
}

 

#if CV_SSE2 可见,如果支持IPP,则会加速。

diff.f = (float)(value - temp);
return temp - (diff.i < 0);

这两句话的技巧:用diff.f保存浮点数。因为是联合体定义的diff,因此当再用diff.i解释那块内存时,可能数值会变化,但数值的正负不会变。

cvCvtColor函数:

cvCvtColor(...),

  参数CV_BGR2GRAY 是RGB到gray,

  参数 CV_GRAY2BGR 是gray 到RGB.

  

处理结果是彩色的,则转灰色就是了:

  cvCvtColor( inputImg, grayImg, CV_BGR2GRAY);

  void cvCvtColor( const CvArr* src, CvArr* dst, int code );

  src

  输入的 8-bit , 16-bit 或 32-bit 单倍精度浮点数影像。

  dst

  输出的 8-bit , 16-bit 或 32-bit 单倍精度浮点数影像。

code

  色彩空间转换,通过定义 CV_<src_color_space>2<dst_color_space> 常数(见下面)。

  函数 cvCvtColor 将输入图像从一个色彩空间转换为另外一个色彩空间。函数忽略 IplImage 头中定义的 colorModel 和 channelSeq 域,所以输入图像的色彩空间应该正确指定 (包括通道的顺序,对RGB空间而言,BGR 意味着布局为 B0 G0 R0 B1 G1 R1 ... 层叠的 24-位格式,而 RGB 意味着布局为 R0 G0 B0 R1 G1 B1 ... 层叠的24-位格式.

函数做如下变换:

  RGB空间内部的变换,如增加/删除 alpha 通道,反相通道顺序,到16位 RGB彩色或者15位RGB彩色的正逆转换(Rx5:Gx6:Rx5),以及到灰度图像的正逆转换,使用:

  RGB[A]->Gray: Y=0.212671*R + 0.715160*G + 0.072169*B + 0*A

  Gray->RGB[A]: R=Y G=Y B=Y A=0

  所有可能的图像色彩空间的相互变换公式列举如下:

  RGB<=>XYZ (CV_BGR2XYZ, CV_RGB2XYZ, CV_XYZ2BGR, CV_XYZ2RGB):

  |X| |0.412411 0.357585 0.180454| |R|

  |Y| = |0.212649 0.715169 0.072182|*|G|

  |Z| |0.019332 0.119195 0.950390| |B|

  |R| | 3.240479 -1.53715 -0.498535| |X|

  |G| = |-0.969256 1.875991 0.041556|*|Y|

  |B| | 0.055648 -0.204043 1.057311| |Z|

  RGB<=>YCrCb (CV_BGR2YCrCb, CV_RGB2YCrCb, CV_YCrCb2BGR, CV_YCrCb2RGB)

  Y=0.299*R + 0.587*G + 0.114*B

  Cr=(R-Y)*0.713 + 128

  Cb=(B-Y)*0.564 + 128

  R=Y + 1.403*(Cr - 128)

  G=Y - 0.344*(Cr - 128) - 0.714*(Cb - 128)

  B=Y + 1.773*(Cb - 128)

  RGB=>HSV (CV_BGR2HSV,CV_RGB2HSV)

  V=max(R,G,B)

  if V!=0 then S=(V-min(R,G,B))*255/V;

  else S = 0;

  if V=R then H = (G - B)*60/S;

  if V=G then H = 180+(B - R)*60/S;

  if V=B then H = 240+(R - G)*60/S;

  if H<0 then H=H+360;

  使用上面从 0° 到 360° 变化的公式计算色调(hue)值,确保它们被 2 除后能适用于8位。

  RGB=>Lab (CV_BGR2Lab, CV_RGB2Lab)

  |X| |0.433910 0.376220 0.189860| |R/255|

  |Y| = |0.212649 0.715169 0.072182|*|G/255|

  |Z| |0.017756 0.109478 0.872915| |B/255|

  L = 116*Y1/3 for Y>0.008856

  L = 903.3*Y for Y<=0.008856

  a = 500*(f(X)-f(Y))

  b = 200*(f(Y)-f(Z))

  where f(t)=t1/3 for t>0.008856

  f(t)=7.787*t+16/116 for t<=0.008856

  Bayer=>RGB (CV_BayerBG2BGR, CV_BayerGB2BGR, CV_BayerRG2BGR, CV_BayerGR2BGR, CV_BayerBG2RGB, CV_BayerRG2BGR, CV_BayerGB2RGB, CV_BayerGR2BGR, CV_BayerRG2RGB, CV_BayerBG2BGR, CV_BayerGR2RGB, CV_BayerGB2BGR)

像素点安排

  Bayer 模式被广泛应用于 CCD 和 CMOS 摄像头. 它允许从一个单独平面中得到彩色图像,该平面中的 R/G/B 象素点被安排如下:

  R G R G R

  G B G B G

  R G R G R

  G B G B G

  R G R G R

  G B G B G

  对像素输出的RGB份量由该像素的1、2或者4邻域中具有相同颜色的点插值得到。以上的模式可以通过向左或者向上平移一个像素点来作一些修改。转换常量CV_BayerC1C22{RGB|RGB}中的两个字母C1和C2表示特定的模式类型:颜色份量分别来自于第二行,第二和第三列。比如说,上述的模式具有很流行的"BG"类型。

 

cvEqualizeHist函数:

该算法可以恢复正常亮度增加图像的对比度.

void cvEqualizeHist(

   IplImage src,

   IplImage dst

);

src

The input 8-bit single-channel image

dst

The output image of the same size and the same data type as

 

 

cvClearMemStorage:

void cvClearMemStorage( CvMemStorage* storage );
 + 
 +;storage : 存储存储块
 + 
 +函数 cvClearMemStorage 将存储块的 top 置到存储块的头部(注:清空存储块中的存储内容)。该函数并不释放内存(仅清空内存)。假使该内存块有一个父内存块(即:存在一内存块与其有父子关系),则函数就将所有的块返回给其 parent.
void cvClearMemStorage( CvMemStorage* storage );
  storage : 存储存储块 
    函数 cvClearMemStorage 将存储块的 top 置到存储块的头部(注:清空存储块中的存储内容)。该函数并不释放内存(仅清空内存)。假使该内存块有一个父内存块(即:存在一内存块与其有父子关系),则函数就将所有的块返回给其 parent.
void cvClearMemStorage( CvMemStorage* storage );
 + 
 +;storage : 存储存储块
 + 
 +函数 cvClearMemStorage 将存储块的 top 置到存储块的头部(注:清空存储块中的存储内容)。该函数并不释放内存(仅清空内存)。假使该内存块有一个父内存块(即:存在一内存块与其有父子关系),则函数就将所有的块返回给其 parent.

<think>嗯,用户问的是关于C语言中图像处理函数库实现的信息。首先,我需要回忆一下C语言常用的图像处理库。OpenCV应该是比较主要的,虽然它本身是用C++写的,但也有C接口。然后,可能还有像CImg这样的库。用户提到他们之前的问题和引用,所以得注意引用里的内容。引用1提到C语言和OpenCV,引用2和3讲到了具体的函数,比如getimage、putimage,还有resize相关的cvResize。 用户的需求是查找C语言的图像处理函数库,所以需要整理几个常用的库,并说明它们的功能和基本用法。可能需要分点回答,比如基础函数库、高级库、实现方法等。还要注意用户可能对性能、实际应用场景感兴趣。 要确保回答符合格式要求:行内公式用$,独立公式用$$,正确的中文,生成相关问题。引用标记要加在适当的位置,比如提到OpenCV时引用引用1和3,提到图形函数时引用引用2。 另外,用户可能想知道如何自己实现基础函数,比如像素操作、滤波算法,这些在引用1和2里都有涉及。需要解释如何用C语言操作像素,比如二维数组遍历,指针操作。滤波部分可以举例均值滤波,并给出代码示例,注意代码用正确的语法,比如二维数组和嵌套循环。 可能还需要提到注意事项,比如性能优化、边界处理,这些在引用2里提到过,比如图像大小限制和边界情况。最后生成的相关问题要围绕库比较、底层实现、性能优化、与C++的区别,以及具体算法实现,比如边缘检测。 得确保回答结构清晰,分点说明,每个部分有示例代码或公式,并且正确引用。避免使用Markdown,用自然的中文段落,同时符合用户给的系统级指令。</think>在C语言中实现图像处理功能通常需要结合基础编程方法和专业函数库。以下分三个层次说明实现方式及典型函数库: 一、基础图像处理函数实现原理 1. 像素级操作通过二维数组存储图像数据,使用指针进行高效访问: ```c unsigned char image[HEIGHT][WIDTH]; // 灰度图像存储 for(int y=0; y<HEIGHT; y++){ for(int x=0; x<WIDTH; x++){ image[y][x] = 255 - image[y][x]; // 反色处理 } } ``` 2. 常用滤波算法实现(以3x3均值滤波为例): $$output(x,y) = \frac{1}{9}\sum_{i=-1}^{1}\sum_{j=-1}^{1}input(x+i,y+j)$$ 二、主流图像处理库 1. OpenCV C接口(核心功能): - 图像读写:cvLoadImage()/cvSaveImage() - 尺寸变换:cvResize() 实现双线性插值[^3] - 颜色转换:cvCvtColor() 实现RGB↔HSV转换 - 特征检测:cvCanny() 边缘检测 2. C标准图形库(适合基础操作): - getimage()/putimage() 实现图像存取[^2] - 画布操作:setactivepage()/setvisualpage() 3. 轻量级库CImg: - 提供模板化的图像处理类 - 支持傅里叶变换等高级操作 三、典型实现流程示例(边缘检测): ```c IplImage* edge_detect(IplImage* src) { IplImage* gray = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1); cvCvtColor(src, gray, CV_BGR2GRAY); // 色彩空间转换[^1] IplImage* edges = cvCreateImage(cvGetSize(gray), IPL_DEPTH_8U, 1); cvCanny(gray, edges, 50, 150); // Canny边缘检测[^1] cvReleaseImage(&gray); return edges; } ``` 注意事项: 1. 内存管理需严格配对create/release 2. 处理大图像时注意64K限制[^2] 3. 并行优化可使用OpenMP指令
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值