Chapter 1: course

1.1 Why not make the aperture as small as possible?

  • The quantity of light is too small.
  • Lead to diffraction衍射 if the aperture is too small.
  • Difficult to control.

1.2 Changing the aperture size affects depth of field

1.2.1 概述

景深的“景”是指我们要拍摄的景物,“深”就是清晰度的纵深范围。当镜头对焦于拍摄目标时,这一点对应在相机的感光元件上能清晰成像。它前后一定范围内的景物也能被记录得较为清晰,这个范围就是景深。景深越大,纵深景物的清晰范围也就越大。景深越小,纵深景物的清晰范围也就越小。影响景深的三大要素是:

  1. 光圈:在镜头焦距及距离不变的情况下,光圈越小,景深越大,反之亦然。
  2. 距离:在镜头焦距及光圈不变的情况下,越接近拍摄的目标,景深越小,越远离拍摄的目标,景深越大。
  3. 焦距:在距离及光圈不变的情况下,镜头焦距越短,景深越大。即短焦镜头的景深大,长焦镜头的景深小。

1.2.2 原理

在焦点前后,光线开始聚集和扩散,点的影象变成模糊的,形成一个扩大的圆,这个圆就叫做弥散圆。

现实当中,观赏拍摄的影象是以某种方式(比如投影、放大成照片等等)来观察的,人的肉眼所感受到的影象与放大倍率、投影距离及观看距离有很大的关系,如果弥散圆的直径小于人眼的鉴别能力,在一定范围内实际影象产生的模糊是不能辨认的。这个不能辨认的弥散圆就称为容许弥散圆。

景深:

在焦点前后各有一个容许弥散圆,这两个弥散圆之间的距离就叫景深,即:在被摄主体(对焦点)前后,其影像仍然有一段清晰范围的,就是景深。换言之,被摄体的前后纵深,呈现在底片面的影象模糊度,都在容许弥散圆的限定范围内。

景深随镜头的焦距、光圈值、拍摄距离而变化。对于固定焦距和拍摄距离,使用光圈越小,也就是镜片的直径越小,景深越大,和镜头的通光量无关。

从焦点到近处容许弥散圆的的距离叫前景深,从焦点到远方容许弥散圆的距离叫后景深。

1.3 The principle imaging process of DC

  1. When taking photograph, the light from the scene goes through the lens and reaches CCD.
  2. When CCD being exposed, the photodiode光电二极管 is stimulated to release charges, and produces electrical signals.
  3. CCD controlling chip controls the electric flow through the controlling signal circuit in photoperceptive 感光的component. CCD will collect such electrical signals and output them to an amplifier放大器.
  4. After amplifying and filtering, the electrical signals reach ADC. And ADC transfer such electrical signals (continuous) to digital ones (discrete). The value of digital signal is proportional to the intensity of electrical signal and voltage. These values are corresponding to those of an image.
  5. But the above data cannot be treated as image directly. They will be further processed by DSP (digital signal processing). In DSP, color correction and white balance will be performed to obtain a qualified image, and the image will be encoded into the supported format and resolution, which can be stored as a image file.
  6. After the above steps, the image file appears on your memory card and can be previewed.

总结:电荷耦合器件(CCD)接收光学镜头传递来的影像->模拟信号->ADC(连续信号->离散)->DSP(色彩校正、白平衡)->储存到内存卡上

1.4 Digital image representation

Digital image can be represented as a 2D array or matrix

Each pixel in a grayscale image is represented by a byte (8 bits), which covers 256 degrees by [0…255]

Each pixel in a color image is represented by 3 bytes (24 bits), which are for R (red), G (Green) and B (Blue), respectively.

1.3.1 color

Color can be divided into chromatic color and achromatic color.

Chromatic color means the monochrome color (red, yellow, blue, etc.) and their combination. The colorful objects reflect the light selectively to the light spectrum of different wavelengths. Hence, they present different color under white light.

Achromatic color, also called non- chromatic color OR grayscale, means white, black and the gray intensities between them. The achromatic objects do not select the wavelength, so they are in neutral color.

1.3.2 Retina

Retina is the most important part of human eyes, like the film in an camera, to capture the light and produce image. There are two kinds of vision cell on the retina: rods and cones.

  • Rods: ~100, 000, 000, sensitive to light but cannot identify different colors.
  • Cones: ~6,000,000-7,000,000, work under strong light, but can identify different colors.

视细胞:又名感光细胞,分视杆细胞和视锥细胞。人视网膜有视杆细胞约12000万个,对弱光刺激敏感;视锥细胞有650万~700万个,对强光和颜色敏感。

1.3.3 Properties of color vision

Weber’s law

韦伯发现同一刺激差别量必须达到一定比例,才能引起差别感觉。这一比例是个常数,用公式表示:ΔI(差别阈限)/I(标准刺激强度)=k(常数/韦伯分数),这就是韦伯定律。图中,背景强度在一定范围内,这个比值是不变的。

1.3.4 Perception priority and sensitivity

  • 优先级:在同样的环境中,人类首先感知色调(H)变化,饱和(S),再然后明度值(V)
  • 灵敏度:人眼对明度变化最敏感,有最好的分辨率,这也是人眼能进行高动态光照渲染(HDR)的原因。

1.3.5 Color space

设备依赖的颜色空间模型

  • RGB Color + light, energy increases.
  • CMYK Light-Pigment mixture, energy decreases.
  • HSV Hue色调, Saturation饱和度, Intensity/Value明度。优点:色差感知与HSV锥体上的欧氏距离成正比。

非设备依赖的颜色空间模型

CIE颜色模型是一系列根据人眼对RGB仔细衡量的颜色模型,帮助人们在不同的设备,如扫描仪,显示器和打印机上一致地再现颜色。

  • CIE XYZ
  • CIE L∗a∗bL*a*bL∗a∗b
  • CIE YUV

颜色空间之间的转换

1. RGB<->CMY

C=255−RC=255-RC=255−R

M=255−GM=255-GM=255−G

Y=255−BY=255-BY=255−B

2.RGB<->HSV

RGB<->XYZ <->HSV

3. RGB<->YUV

1.3.6 图像存储格式

a.bmp文件

windows中 .bmp=.bid
大部分情况下bmp文件是非压缩的,但是,bmp也支持run-length-encoding行程长度编码。如"AAAABBBCCDEEEE",经过变动长度编码法可将资料压缩为4A3B2C1D4E。

bmp文件头:

位图信息头:

调色盘和图像数据:

调色板其实是一张映射表,标识颜色索引号与其代表的颜色的对应关系。它在文件中的布局就像一个二维数组palette[N][4],其中N表示总的颜色索引数,每行的四个元素分别表示该索引对应的B、G、R和Alpha的值,每个分量占一个字节。如不设透明通道时,Alpha为0。因为前面知道,本图有256个颜色索引,因此N = 256。索引号就是所在行的行号,对应的颜色就是所在行的四个元素。这里截取一些数据来说明:

索引:(蓝,绿,红,Alpha)

0号:(fe,fa,fd,00)

1号:(fd,f3,fc,00)

2号:(f4,f3,fc,00)

3号:(fc,f2,f4,00)

4号:(f6,f2,f2,00)

5号:(fb,f9,f6,00) 等等。

一共有256种颜色,每个颜色占用4个字节,就是一共1024个字节,再加上前面的文件信息头和位图信息头的54个字节加起来一共是1078个字节。也就是说在位图数据出现之前一共有1078个字节,与我们在文件信息头得到的信息:文件头到文图数据区的偏移为1078个字节一致!

四、位图数据

下面就是位图数据了,每个像素占一个字节,取得这个字节后,以该字节为索引查询相应的颜色,并显示到相应的显示设备上就可以了。

注意:由于位图信息头中的图像高度是正数,所以位图数据在文件中的排列顺序是从左下角到右上角,以行为主序排列的。

也即我们见到的第一个像素60是图像最左下角的数据,第二个人像素60为图像最后一行第二列的数据,…一直到最后一行的最后一列数据,后面紧接的是倒数第二行的第一列的数据,依此类推。

如果图像是24位或是32位数据的位图的话,位图数据区就不是索引而是实际的像素值了。下面说明一下,此时位图数据区的每个像素的RGB颜色阵列排布:

24位RGB按照BGR的顺序来存储每个像素的各颜色通道的值,一个像素的所有颜色分量值都存完后才存下一个下一个像素,不进行交织存储。

32位数据按照BGRA的顺序存储,其余与24位位图的方式一样。

每行的bytes数必须是4的倍数,否则就用00补成4的倍数。6 bytes that represent a row in the bitmap:A0 37 F2 8B 31 C4 must be saved as: A0 37 F2 8B 31 C4 00 00

Chapter 2: assignment

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
typedef unsigned short UINT16;
typedef unsigned long DWORD;
typedef unsigned char UNCHAR;
//存储bmp文件头
typedef struct tagBITMAPFILEHEADER
{//  UINT16 bfType;         //B M 加上这一行整个结构体就占16个字节,去掉就占12个字节,不知道为什么 DWORD  bfSize;         //size of fileUINT16 bfReserved1;UINT16 bfReserved2;DWORD bfOffBits;       //header offset
}BITMAPFILEHEADER;         //14字节
//存储位图信息头
typedef struct tagBITMAPINFOHEADER{DWORD biSize;          //信息头大小 DWORD biWidth;         //图像宽度DWORD biHeight;        //图像高度UINT16 biPlanes;       //图像的面位数UINT16 biBitCount;     //每个像素的位数 DWORD biCompression;   //压缩类型 DWORD biSizeImage;     //图文件大小 DWORD biXPelsPerMeter; //水平分辨率DWORD biYPelsPerMeter; //垂直分辨率DWORD biClrUsed;       //使用的色彩数DWORD biClrImportant;  //重要的颜色数
}BITMAPINFOHEADER;         //40字节
//储存rgb图像信息
typedef struct tagrbgIMAGE{UNCHAR **r;//指向二维矩阵,表示图像的R信息 UNCHAR **g;//指向二维矩阵,表示图像的G信息 UNCHAR **b;//指向二维矩阵,表示图像的B信息
}rgbIMAGE;
typedef rgbIMAGE *rgbIMAGEINFO;
//存储yuv图像信息
typedef struct tagyuvIMAGE{UNCHAR **y;//指向二维矩阵,表示图像的Y信息 char **u;//指向二维矩阵,表示图像的U信息 char **v; //指向二维矩阵,表示图像的V信息
}yuvIMAGE;
typedef yuvIMAGE *yuvIMAGEINFO;
//存储调色盘图像信息
typedef struct RGBQUAD{UNCHAR rgbBlue;UNCHAR rgbGreen;UNCHAR rgbRed;UNCHAR rgbReserved;
};
/***@brief 显示位图文件头信息 *@param[in] pBmpHead 指向位图文件头结构体
*/
void showBmpHead(BITMAPFILEHEADER* pBmpHead);
/***@brief 显示位图信息头 *@param[in] pBmpInforHead 指向位图信息头结构体
*/
void showBmpInfoHead(BITMAPINFOHEADER* pBmpInforHead);
/***@brief 读取bmp文件图像数据*@param[in] pBmpHead: 指向位图文件头结构体*          pBmpInforHead: 指向位图信息头结构体 *           fp: 指向位图文件返回的文件指针 *@return  一个存储rgb图像信息的结构体
*/
rgbIMAGEINFO bmp2rgb(BITMAPFILEHEADER* pBmpHead,BITMAPINFOHEADER* pBmpInforHead,FILE* fp);
/***@brief 将rgb图像数据经过变化得到rgb图像数据 *@param[in] rgb: 存储rgb图像数据的结构体 *          height: 图像的高 *          width: 图像的宽 *@return  一个存储yuv图像信息的结构体
*/
yuvIMAGEINFO rgb2yuv(rgbIMAGEINFO rgb,int height,int width);
/***@brief 求出一个二维矩阵的最大值或最小值 *@param[in] a: 表示二维矩阵 *          row: 二维矩阵的行数 *          col: 二维矩阵的列数*          choice: 1则返回二维矩阵最大值,2则返回二维矩阵最小值 *@return  返回二维矩阵的最大值或最小值
*/
UNCHAR findmaxorminnum(UNCHAR **a,int row,int col,int choice);
/***@brief 将一个二维矩阵的中的数都限定在[0,255] 之间 *@param[in] a: 表示二维矩阵 *          row: 二维矩阵的行数 *          col: 二维矩阵的列数*@return  返回处理后的二维矩阵
*/
UNCHAR **rearrange(UNCHAR **a,int row,int col);
int main(){//open bmp fileFILE *fpbmp; FILE *fpout,*fpout2;UINT16 bm;BITMAPFILEHEADER bmpfileheader;    //指向bmp文件头 BITMAPINFOHEADER bmpinfoheader;    //指向bmp信息头 BITMAPFILEHEADER targetfileheader; //指向目标bmp 文件头 BITMAPINFOHEADER targetinfoheader; //指向目标bmp 信息头 rgbIMAGEINFO rgbPicPoint;          //指向存储rgb图信息的结构体 rgbIMAGEINFO outrgb;               //指向yuv转到rgb的图信息的结构体 yuvIMAGEINFO yuvPicPoint;          //指向存储yuv图信息的结构体 int row,col;int i,j;//只读打开一个二进制文件 fpbmp=fopen("lena.bmp","rb");//如果文件读取失败,返回空指针 if(fpbmp==NULL){printf("Can not open the picture!");return 0;} //让fpbmp指向bmp文件的开始fseek(fpbmp,0,SEEK_SET);//读取文件信息fread(&bm,sizeof(UINT16),1,fpbmp);                       //单独读取说明文件类型的两个字节 fread(&bmpfileheader,sizeof(BITMAPFILEHEADER),1,fpbmp);  //读取文件头信息 fread(&bmpinfoheader,sizeof(BITMAPINFOHEADER),1,fpbmp);  //读取信息头信息 showBmpHead(&bmpfileheader);                             //输出文件头信息 printf("**********************************************\n");showBmpInfoHead(&bmpinfoheader);                         //输出信息头信息 printf("**********************************************\n");int width;int height;  if(bmpinfoheader.biBitCount>=24){rgbPicPoint=bmp2rgb(&bmpfileheader,&bmpinfoheader,fpbmp);width=bmpinfoheader.biWidth;                         //图像的宽    height=bmpinfoheader.biHeight;                       //图像的高 }//将RGB图片转为YUVyuvPicPoint=rgb2yuv(rgbPicPoint,height,width);//Rearrange gray intensity to lie between [0,255]UNCHAR**grayimage=(UNCHAR**)malloc(sizeof(UNCHAR*)*height);for(row=0;row<height;row++){grayimage[row]=(UNCHAR*)malloc(sizeof(UNCHAR)*width);}grayimage=rearrange(yuvPicPoint->y,height,width);/*Write a grayscale bmp*/
//  for(i=0;i<1;i++){//      for(j=0;j<width;j++){//          printf("%d ",yuvPicPoint->y[i][j]);
//      }
//   }
//  //构造灰度图的调色板
//  RGBQUAD* rgbquad;
//  rgbquad=(RGBQUAD*)malloc(sizeof(RGBQUAD)*256);
//  for(i=0;i<256;i++){//      rgbquad[i].rgbBlue=i;
//      rgbquad[i].rgbGreen=i;
//      rgbquad[i].rgbRed=i;
//      rgbquad[i].rgbReserved=0;
//  }
//  //构造灰度图的文件头
//  targetfileheader.bfSize=width*height+sizeof(RGBQUAD)*256+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
//  targetfileheader.bfReserved1=0;
//  targetfileheader.bfReserved2=0;
//  targetfileheader.bfOffBits=sizeof(RGBQUAD)*256+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
//  //构造灰度图的信息头
//  targetinfoheader.biBitCount=8;
//    targetinfoheader.biSize=sizeof(BITMAPINFOHEADER);
//    targetinfoheader.biHeight=height;
//    targetinfoheader.biWidth=width;
//    targetinfoheader.biPlanes=1;
//    targetinfoheader.biCompression=0;
//    targetinfoheader.biSizeImage=0;
//    targetinfoheader.biXPelsPerMeter=0;
//    targetinfoheader.biYPelsPerMeter=0;
//    targetinfoheader.biClrImportant=256;
//    targetinfoheader.biClrUsed=256;//将信息写入文件fpout=fopen("gray.bmp","wb");if(fpout==NULL){printf("Can not write the file!");}
//  else{//      printf("ok");
//      fwrite(&bm,sizeof(UINT16),1,fpout);
//      fwrite(&targetfileheader,sizeof(BITMAPFILEHEADER),1,fpout);
//      fwrite(&targetinfoheader,sizeof(BITMAPINFOHEADER),1,fpout);
//      fwrite(rgbquad,sizeof(RGBQUAD),256,fpout);
//      fwrite(grayimage,sizeof(UNCHAR),height*width,fpout);
//      fclose(fpout);
//  }else{fwrite(&bm,sizeof(UINT16),1,fpout);                           //将文件类型写入文件 fwrite(&bmpfileheader,sizeof(BITMAPFILEHEADER),1,fpout);      //将文件头写入文件 fwrite(&bmpinfoheader,sizeof(BITMAPINFOHEADER),1,fpout);      //将信息头写入文件 UNCHAR *gray=(UNCHAR*)malloc(sizeof(UNCHAR)*height*width*3);  //用一个行向量储存图像数据 //将图像按24位存储,并将原二维数列扩充3倍,放入一维矩阵 for(row=0;row<height;row++){for(col=0;col<width;col++){gray[3*(row*height+col)]=grayimage[row][col];gray[3*(row*height+col)+1]=grayimage[row][col];gray[3*(row*height+col)+2]=grayimage[row][col];}}//将这个一维数列表示的图像数据写入文件 fwrite(gray,sizeof(UNCHAR),height*width*3,fpout);//关闭写入的文件 fclose(fpout);printf("Successfully obtained grayscale image!\n");    }//Change the luminance value Yfor(row=0;row<height;row++){for(col=0;col<width;col++){yuvPicPoint->y[row][col]+=5;}}//yuv->rgboutrgb=(rgbIMAGEINFO)malloc(sizeof(rgbIMAGE));//初始化 outrgb->b=(UNCHAR**)malloc(sizeof(UNCHAR*)*height);for(row=0;row<height;row++){outrgb->b[row]=(UNCHAR*)malloc(sizeof(UNCHAR)*width);}  outrgb->g=(UNCHAR**)malloc(sizeof(UNCHAR*)*height);for(row=0;row<height;row++){outrgb->g[row]=(UNCHAR*)malloc(sizeof(UNCHAR)*width);} outrgb->r=(UNCHAR **)malloc(sizeof(UNCHAR*)*height);for(row=0;row<height;row++){outrgb->r[row]=(UNCHAR*)malloc(sizeof(UNCHAR)*width);}//Rearrange gray intensity to lie between [0,255]; yuvPicPoint->y=rearrange(yuvPicPoint->y,height,width);//通过公式将yuv转换为rgbfor(row=0;row<height;row++){for(col=0;col<width;col++){outrgb->r[row][col]=UNCHAR(1.0000*yuvPicPoint->y[row][col]+1.1398*yuvPicPoint->v[row][col]);outrgb->g[row][col]=UNCHAR(0.9996*yuvPicPoint->y[row][col]-0.3954*yuvPicPoint->u[row][col]-0.5805*yuvPicPoint->v[row][col]);outrgb->b[row][col]=UNCHAR(1.0020*yuvPicPoint->y[row][col]+2.0361*yuvPicPoint->u[row][col]-0.0005*yuvPicPoint->v[row][col]);               }}//write a color bmpfpout2=fopen("lenaps.bmp","wb");if(!fpout2){printf("Wrong!Can not open the file!\n");}fwrite(&bm,sizeof(UINT16),1,fpout2);                              //文件类型写入文件 fwrite(&bmpfileheader,sizeof(BITMAPFILEHEADER),1,fpout2);         //将文件头写入文件  fwrite(&bmpinfoheader,sizeof(BITMAPINFOHEADER),1,fpout2);         //将信息头写入文件UNCHAR *rgb2=(UNCHAR*)malloc(sizeof(UNCHAR)*height*width*3);    //用一个行向量储存图像数据    //按照bgr的顺序将3个二维矩阵存储为一个一维矩阵 for(row=0;row<height;row++){for(col=0;col<width;col++){rgb2[3*(row*height+col)]=outrgb->b[row][col];rgb2[3*(row*height+col)+1]=outrgb->g[row][col];rgb2[3*(row*height+col)+2]=outrgb->r[row][col];}}//将这个一维数列表示的图像数据写入文件 fwrite(rgb2,sizeof(UNCHAR),height*width*3,fpout2);//关闭文件 fclose(fpout2);printf("Successfully obtained RGB image!\n");    system("pause"); return 0;
}rgbIMAGEINFO bmp2rgb(BITMAPFILEHEADER* pBmpHead,BITMAPINFOHEADER* pBmpInforHead,FILE* fp){int bfoffbits=pBmpHead->bfOffBits;    //从文件头开始到实际图像数据之间的字节的偏移量 rgbIMAGEINFO imageinfo=(rgbIMAGEINFO)malloc(sizeof(rgbIMAGE));int row,col;   fseek(fp,bfoffbits,SEEK_SET);int width=pBmpInforHead->biWidth;     //获得图像的高 int height=pBmpInforHead->biHeight;   //获得图像的宽 //初始化 imageinfo->b=(UNCHAR**)malloc(sizeof(UNCHAR*)*height);for(row=0;row<height;row++){imageinfo->b[row]=(UNCHAR*)malloc(sizeof(UNCHAR)*width);}  imageinfo->g=(UNCHAR**)malloc(sizeof(UNCHAR*)*height);for(row=0;row<height;row++){imageinfo->g[row]=(UNCHAR*)malloc(sizeof(UNCHAR)*width);}   imageinfo->r=(UNCHAR **)malloc(sizeof(UNCHAR*)*height);for(row=0;row<height;row++){imageinfo->r[row]=(UNCHAR*)malloc(sizeof(UNCHAR)*width);}  //读取图像rgb信息 for(row=0;row<height;row++){for(col=0;col<width;col++){fread(&imageinfo->b[row][col],sizeof(UNCHAR),1,fp);fread(&imageinfo->g[row][col],sizeof(UNCHAR),1,fp);fread(&imageinfo->r[row][col],sizeof(UNCHAR),1,fp);}}return imageinfo;
}yuvIMAGEINFO rgb2yuv(rgbIMAGEINFO rgb,int height,int width){yuvIMAGEINFO yuv=(yuvIMAGEINFO)malloc(sizeof(yuvIMAGE));if(!yuv){printf("Out of the memory!");return NULL;}int row,col;//初始化 yuv->y=(UNCHAR**)malloc(sizeof(UNCHAR*)*height);for(row=0;row<height;row++){yuv->y[row]=(UNCHAR*)malloc(sizeof(UNCHAR)*width);}  yuv->u=(char**)malloc(sizeof(char*)*height);for(row=0;row<height;row++){yuv->u[row]=(char*)malloc(sizeof(char)*width);}yuv->v=(char**)malloc(sizeof(char*)*height);for(row=0;row<height;row++){yuv->v[row]=(char*)malloc(sizeof(char)*width);}  //用公式将rgb信息转换为yuv for(row=0;row<height;row++){for(col=0;col<width;col++){yuv->y[row][col]=UNCHAR(0.299*rgb->r[row][col]+0.587*rgb->g[row][col]+0.144*rgb->b[row][col]);yuv->u[row][col]=char(-0.147*rgb->r[row][col]-0.289*rgb->g[row][col]+0.435*rgb->b[row][col]);yuv->v[row][col]=char(0.615*rgb->r[row][col]-0.515*rgb->g[row][col]-0.100*rgb->b[row][col]);                      }}return yuv;
}UNCHAR findmaxorminnum(UNCHAR **a,int row,int col,int choice){UNCHAR max=0,min=0;int i,j;switch(choice){case 1:for(i=0;i<row;i++){for(j=0;j<col;j++){if(a[i][j]>max){max=a[i][j];}}}return max;      case 2:for(i=0;i<row;i++){for(j=0;j<col;j++){if(a[i][j]<min){min=a[i][j];}}}return min;         }}UNCHAR **rearrange(UNCHAR **a,int row,int col){UNCHAR **rea=(UNCHAR**)malloc(sizeof(UNCHAR*)*row);int i,j;UNCHAR max,min,scope;for(i=0;i<row;i++){rea[i]=(UNCHAR*)malloc(sizeof(UNCHAR)*col);}    max=findmaxorminnum(a,row,col,1);min=findmaxorminnum(a,row,col,2);scope=max-min;for(i=0;i<row;i++){for(j=0;j<col;j++){rea[i][j]=UNCHAR(255*(a[i][j]-min)/scope);}}return rea;
}void showBmpHead(BITMAPFILEHEADER* pBmpHead)
{
printf("文件大小:%d\n",pBmpHead->bfSize);
printf("保留字:%d\n",pBmpHead->bfReserved1);
printf("保留字:%d\n",pBmpHead->bfReserved2);
printf("实际位图数据的偏移字节数:%d\n",pBmpHead->bfOffBits);
}  void showBmpInfoHead(tagBITMAPINFOHEADER* pBmpInforHead)
{
printf("位图信息头:\n");
printf("结构体的长度:%d\n",pBmpInforHead->biSize);
printf("位图宽:%d\n",pBmpInforHead->biWidth);
printf("位图高:%d\n",pBmpInforHead->biHeight);
printf("biPlanes平面数:%d\n",pBmpInforHead->biPlanes);
printf("biBitCount采用颜色位数:%d\n",pBmpInforHead->biBitCount);
printf("压缩方式:%d\n",pBmpInforHead->biCompression);
printf("biSizeImage实际位图数据占用的字节数:%d\n",pBmpInforHead->biSizeImage);
printf("X方向分辨率:%d\n",pBmpInforHead->biXPelsPerMeter);
printf("Y方向分辨率:%d\n",pBmpInforHead->biYPelsPerMeter);
printf("使用的颜色数:%d\n",pBmpInforHead->biClrUsed);
printf("重要颜色数:%d\n",pBmpInforHead->biClrImportant);
}

图像信息处理:bmp文件、颜色空间转化、灰度图相关推荐

  1. numpy转PIL.Image: 处理Mask图像为单通道的彩色/灰度图colormap.png

    文章目录 从分割数据集说起 8位彩色图 8位灰度图 1位二值图 什么是图像位深 PNG图像格式简介 如何处理Mask图像 注意!!!PIL一定要手动close 防止内存泄漏 PIL库相关函数 从分割数 ...

  2. 彩色BMP转换成灰度图的原理

    图像处理中,大部分的处理方法都需要事先把彩色图转换成灰度图才能进行相关的计算.识别. 彩色图转换灰度图的原理如下: 我们知道彩色位图是由R/G/B三个分量组成,其文件存储格式为 BITMAPFILEH ...

  3. RGB图像转为灰度图

    最后结论: Grey = (R*38 + G*75 + B*15)>> 7 代码 #include <cv.h> #include <highgui.h>using ...

  4. 数字图像处理大作业-BMP文件的读写

    数字图像处理-BMP文件的读写 一.题目背景 二.灰度BMP的读写 1.读入lena.bmp文件 1.1 编写打印文件头信息与信息头数据的函数 2 通过文件内容得到灰度bmp数据信息 2.1 打印信息 ...

  5. matlab uint8转uint16,MATLAB图像uint8,uint16,double, rgb转灰度解释

    1.uint8,uint16与double 为了节省存储空间,matlab为图像提供了特殊的数据类型uint8(8位无符号整数),以此方式存储的图像称作8位图像.matlab读入图像的数据是uint8 ...

  6. 8、灰度图的腐蚀、膨胀、开闭运算、顶帽底帽

    1. 灰度图的腐蚀 用结构元素的中心点,从左到右从上到下,依次扫描灰度图的像素点,图片上该像素点的值取为结构元素所覆盖区域中像素点的 最小值,扫描一遍后会得到一张新图,就是原图的腐蚀图. 用该结构元素 ...

  7. 2021-07-27 对labelme标注出来的JSON文件进行灰度图转化(标签值0.1.2.3.4)

    对labelme标注出来的JSON文件进行灰度图转化(标签值0.1.2.3.4) 原图如下: 标注后生成json文件如下: import cv2 import numpy as np import j ...

  8. BMP格式图像知识点总结并转灰度图

    24位彩图转换为灰度图练习 练习目的 位图知识点 BMP图像存储结构 位图文件头 位图信息头 调色板 位图数据 转灰度图重点 代码例程 练习目的 BMP格式图片灰度化 位图知识点 刚拿到任务时觉得图像 ...

  9. 图像由彩色图转化为灰度图的三种方法

    一.原理 对于图像由彩色图转化为灰度图有三种方法 分别为 加权法 均值法 最大值法 加权法就是  GRAY==0.3*R+0.59*G+0.11*B 均值法就是 GRAY==(R+G+B)/3 最大值 ...

最新文章

  1. PAT(甲级)2018年冬季考试 7-1 Google Recruitment
  2. Rancher搭建集群
  3. Serverless 解惑——函数计算如何访问 SQL Server 数据库
  4. 分析各种排序算法的优劣
  5. java发邮件_使用MATLAB自动发邮件
  6. linux离线安装python3 devel_linux离线安装python3
  7. 示范NTFS 卷上的硬链接
  8. vue理由设置_在你的下一个Web应用中使用Vue.js的三个理由
  9. oracle 生成 sql语句,Oracle使用SQL语句生成日历的实现方法
  10. 利用搜索引擎实现关键词爬取内容
  11. java线程怎么用_Java多线程基本使用
  12. Linux客户机上安装VMware tools工具方法
  13. 若依框架前端Vue项目分析实战
  14. STM32H7+USB3300+SD作为U盘速度慢的问题
  15. 中国城市云计算首站现场会成都隆重举行
  16. 获取汉字的拼音码(工具类)
  17. like语句太慢 sqlserver_MySQL Like模糊查询速度太慢如何解决
  18. NYOJ326_Dining(最大流)
  19. android绘画板界面,手机绘画板(MediBang Paint Tablet)
  20. 项目笔记 【调查问卷】

热门文章

  1. v7000更换电池步骤_[原创]IBM V7000 SVC更换已经告警的UPS电池详细步骤
  2. 有服务器风扇声音对胎儿有影响吗,怀孕期间长时间噪音对胎儿的影响有哪些
  3. 记录下我磕磕碰碰的三个月找工作经历,完整PDF
  4. java交换机状态_博科SAN交换机的状态等信息查询(华为SNS系列交换机为例OEM博科)...
  5. aistudio解压zip
  6. 小米笔记本桌面没有计算机,没有4K屏幕,只有3.5K,小米笔记本真好用吗?
  7. 百元级冷门高音质蓝牙耳机推荐,300左右为什么不试试这几款蓝牙耳机?
  8. python:list能像数值一样做运算么?
  9. NET 页面生命周期
  10. openstack ice自定义调度算法项目详解(horizon、novaclient、api、scheduler、db、自定义数据库)