摄像头编程并且对图像的处理以及直方图的算法
ov7725数字摄像头编程基本知识笔记

PCLKHREFHSYNC 像素值ov7725数字摄像头编程基本知识笔记这里以ov7725为例,对数字摄像头的时序进行分析。
其他数字摄像头的时序也大同小异。
像素输出顺序数字摄像头输出图像时,一般都是从左到右,有上到下逐个输出(部分芯片可配置输出顺序):有些摄像头有奇偶场,是采用隔行扫描方法,把一帧图象分为奇数场和偶数场两场。
(ov7725没有奇偶场之分)行中断时序0 第一个输出像素最后一个输出像素 最后一个像素 消隐区,如果不按照时序来采集,就有可能采集到消隐区,值为0,即黑色。
行与行之间,场与场之间都一行图像数据 第一个 像素 PCLK 上升沿时,MCU 采集图像;下降沿时,摄像头输出图像。
HREF 和HSYNC 都用于行中断信号,但时序有点区别。
HREF 上升沿就马上输出图像数据,而HSYNC 会等待一段时间再输出图像数据,如果行中断里需要处理事情再开始采集,则显然用HREF 的上升沿是很容易来不两个都是行中断信号,共用同一个管脚,由寄存器配置选择哪个信号输出。
场中断时序采集图像思路①使用for 循环延时采集1. 需要采集图像时,开场中断2. 场中断来了就开启行中断,关闭场中断3. 行中断里用for 循环延时采集像素,可以在行中断里添加标志位,部分行不采集,即可跨行采集。
4. 行中断次数等于图像行数时即可关闭行中断,标志图像采集完毕。
②使用场中断和行中断,DMA 传输1. 需要采集图像时,开场中断2. 场中断来了,开行中断和初始化DMA 传输3. 行中断来了就设置DMA 地址,启动DMA 传输。
如果先过滤部分行不采集,则设置一个静态变量,每次行中断来了都自加1,根据值来选择采集或不采集某些行。
4. 每个PCLK 上升沿来了都触发DMA 传输,把摄像头输出的值读取到内存数组里。
当触发n 次(n=图像列数目)后就停止DMA 传输。
5. 行中断次数等于一幅图像的行数,或者等待下一个场中断来临 就结束图像采集,关闭行中断和场中断。
图像处理算法的开发教程与实现方法

图像处理算法的开发教程与实现方法图像处理是计算机科学领域中一个重要的研究方向,它涉及到对数字图像的获取、处理、分析和识别等一系列操作。
图像处理算法的开发则是实现这些操作的核心。
本文将为读者介绍图像处理算法的开发教程与实现方法。
一、图像处理算法的基本概念图像处理算法是指用来处理数字图像的数学或逻辑操作方法。
在开发图像处理算法之前,我们需要对一些基本概念有所了解。
1. 像素:像素是构成数字图像的最小单元,代表了图像中的一个点。
每个像素都有自己的位置和像素值,像素值可以表示颜色、亮度或灰度等信息。
2. 空间域与频率域:在图像处理算法中,我们常常需要在空间域和频率域之间进行转换。
空间域指的是图像中像素的位置和像素值,而频率域则是指图像中各个频率分量的分布。
3. 直方图:直方图是对图像像素分布的统计图,它可以描述图像中不同像素值的数量。
直方图分析在图像处理中非常重要,可以用来检测图像的亮度、对比度等特征。
二、图像处理算法的开发流程在开发图像处理算法之前,我们需要明确自己的目标并制定开发流程。
一般而言,图像处理算法的开发流程包括以下几个步骤。
1. 图像获取:首先,我们需要获取待处理的图像。
图像可以由摄像机、扫描仪等设备采集获得,也可以从存储设备或网络中读取。
2. 图像预处理:在进行实际的图像处理之前,我们需要对图像进行预处理。
预处理包括图像的去噪、增强、平滑等操作,可以提高后续处理的效果。
3. 图像分割:图像分割是将图像划分为若干个区域的过程。
分割可以基于像素值、纹理、形状等特征进行,常用的分割方法有阈值分割、边缘检测、区域生长等。
4. 特征提取:在图像处理中,我们通常需要从图像中提取出一些重要的特征。
特征可以用来描述图像的形状、颜色、纹理等属性,常用的特征提取方法有哈尔特征、色彩直方图等。
5. 图像识别与分析:通过对提取出的特征进行分类和分析,我们可以实现图像的识别和分析。
图像识别涉及到将图像归类到不同的类别中,而图像分析则是对图像中的目标进行定位、计数等。
摄像头采集信息的算法

摄像头采集信息的算法全文共四篇示例,供读者参考第一篇示例:摄像头在现代社会中扮演着重要角色,不仅在监控系统、安防领域有着广泛的应用,还在智能手机、笔记本电脑、平板电脑等设备中被广泛使用。
摄像头采集信息的算法是指利用摄像头获取的视频信息进行处理和分析的算法,其涉及到图像处理、计算机视觉和人工智能等多个领域,是当前研究热点之一。
摄像头采集信息的算法可以用于多种应用场景,例如人脸识别、车辆识别、动作检测、人体姿态识别等。
在这些应用中,摄像头首先将所拍摄的图像或视频传输至计算机系统中,而后算法会对图像进行分析和处理,从中提取出有意义的信息,并作出相应的判断和行为反应。
对于摄像头采集信息的算法来说,图像处理是其中一个重要的环节。
图像处理技术包括图像的采集、预处理、特征提取和特征匹配等步骤。
在图像采集阶段,摄像头会不断地捕获图像或视频,将其传输至计算机系统中。
在预处理阶段,图像可能需要进行去噪、平滑处理等,以便提高后续处理的效果。
特征提取是指从图像中提取出具有代表性的信息,例如像素级的颜色、纹理、形状等信息。
特征匹配则是将提取出的特征与预先训练好的模型进行匹配,从而实现对图像中物体或场景的识别和分类。
除了图像处理,计算机视觉也是摄像头采集信息的算法中不可或缺的一部分。
计算机视觉是一门研究如何让计算机“看懂”图像或视频的学科,其包括目标检测、目标跟踪、图像识别、物体检测等多个领域。
通过计算机视觉的技术,摄像头可以实现人脸识别、动作检测、人体姿态识别等功能。
在人工智能领域,深度学习和神经网络技术也被广泛应用于摄像头采集信息的算法中。
深度学习是一种基于人工神经网络的机器学习方法,通过大量的训练数据和复杂的网络结构,可以实现更加精准的图像识别和分类。
神经网络模仿了人脑的神经元网络结构,在处理图像时可以提取出更多的高级特征,提高图像处理的准确性和效率。
在工业领域,摄像头采集信息的算法也被广泛应用于生产自动化和机器视觉系统中。
sift算法原理

sift算法原理SIFT算法原理。
SIFT(Scale-invariant feature transform)算法是一种用于图像处理和计算机视觉领域的特征提取算法。
它能够在不同尺度和旋转角度下提取出稳定的特征点,并且对光照、噪声等干扰具有较强的鲁棒性。
SIFT算法由David Lowe于1999年提出,至今仍被广泛应用于图像拼接、目标识别、三维重建等领域。
本文将介绍SIFT算法的原理及其关键步骤。
1. 尺度空间极值检测。
SIFT算法首先通过高斯滤波构建图像的尺度空间金字塔,然后在不同尺度空间上寻找局部极值点作为关键点。
这些关键点在不同尺度下具有不变性,能够在不同大小的目标上被检测到。
2. 关键点定位。
在尺度空间极值点的基础上,SIFT算法通过对尺度空间进行插值,精确定位关键点的位置和尺度。
同时,为了提高关键点的稳定性,还会对梯度方向进行进一步的精确计算。
3. 方向分配。
为了使关键点对旋转具有不变性,SIFT算法会计算关键点周围像素点的梯度方向直方图,并选择主方向作为关键点的方向。
这样可以使得关键点对于图像的旋转具有不变性。
4. 特征描述。
在确定了关键点的位置、尺度和方向后,SIFT算法会以关键点为中心,提取周围区域的梯度信息,并将其转换为具有较强区分度的特征向量。
这些特征向量可以很好地描述关键点周围的图像信息,从而实现对图像的匹配和识别。
5. 特征匹配。
最后,SIFT算法使用特征向量进行特征匹配,通常采用欧氏距离或者余弦相似度进行特征匹配。
通过匹配不同图像的特征点,可以实现图像的配准、目标的识别等应用。
总结。
SIFT算法作为一种经典的特征提取算法,在图像处理和计算机视觉领域具有重要的应用价值。
其关键在于通过尺度空间极值点的检测和特征描述子的构建,实现了对图像的稳健特征提取。
同时,SIFT算法对于光照、噪声等干扰具有较强的鲁棒性,能够应对复杂环境下的图像处理任务。
因此,SIFT算法在目标识别、图像拼接、三维重建等领域有着广泛的应用前景。
ENVI实习直方图匹配,校正,分类

ENVI实习一实验目的(1)主要学习ENVI软件的基本功能(2)ENVI 软件完成影像增强(包括直方图匹配和去云)、融合、正射校正和监督、非监督分类四个大方面的试验。
(3)掌握视窗操作模块的功能和操作技能二软件和设备ENVI4.5一套三实验原理各个任务的试验原理和操作详细见下面操作,再次不详述。
一、图像增强(算法、原理、对比图)1、直方图匹配在ENVI 中使用Histogram Matching 工具可以自动地把一幅实现图像的直方图匹配到另一幅上,从而使两幅图像的亮度分布尽可能地接近。
使用该功能以后,在该功能被启动的窗口内,输入直方图将发生变化,以与所选图像显示窗口的当前输出直方图相匹配。
在灰阶和彩色图像上,都可以使用该功能。
操作步骤:选择Enhance > Histogram Matching,出现Histogram Matching Input parameters 对话框,在Match To中选择想匹配的图像。
在Input Histogram 会有Image、Scroll、Zoom、Band、、ROI来选择如数直方图的来源,下图为输入图像数据及其所用的拉伸(直方图匹配之前):下图为Match To 想匹配的图像及其拉伸:利用直方图匹配后图像2的直方图结果:从结果可以看出,匹配后的图像在亮度上已经明显增强,从偏暗增强为较亮;其直方图与#1中的图像直方图在亮度上分布也很接近。
2、图像去云常规的云处理算法会随云的覆盖类型的不同而不同,对在大范围内存在薄云的影像来说,采用同态滤波法较好。
同态滤波法把频率过滤与灰度变化结合起来,分离云与背景地物,最终从影像中去除云的影响,这种方法由于涉及到滤波器以及截至频率的选择,在滤波的过程中有时会导致一些有用信息的丢失。
对于局部有云的影像来说,一般使用时间平均法,这种算法适用于地物特征随时间变化较小的地区,如荒漠、戈壁等地区;对于植被覆盖茂密的地区,由于植被的长势与时间有密切的关系,不同时相的植被长势在影像中有明显的区别,这种简单的替代算法不再适用。
了解图像识别和处理的基本原理和算法

了解图像识别和处理的基本原理和算法图像识别和处理是计算机视觉领域的重要研究方向,它涉及到对图像进行分析、理解和处理的技术和方法。
本文将介绍图像识别和处理的基本原理和算法。
一、图像识别的基本原理图像识别是指通过计算机对图像进行分析和理解,从而识别出图像中的对象、场景等信息。
其基本原理包括以下几个方面:1. 特征提取:特征是图像中的一些具有代表性的属性或者模式,通过提取这些特征可以描述图像的内容。
常用的特征包括颜色、纹理、形状等。
特征提取可以通过局部特征描述子(如SIFT、SURF等)或者深度学习模型(如卷积神经网络)来实现。
2. 特征匹配:将待识别图像的特征与已知图像库中的特征进行匹配,找出最相似的图像。
匹配算法可以使用最近邻算法、支持向量机等。
3. 分类器训练:通过使用已标注的图像数据集来训练分类器,使其能够自动学习图像的特征和类别之间的关系。
常用的分类器包括支持向量机、随机森林、深度学习模型等。
二、图像处理的基本原理图像处理是指对图像进行各种操作和变换,以改善图像的质量、增强图像的特征或者提取图像中的有用信息。
其基本原理包括以下几个方面:1. 图像增强:通过对图像的亮度、对比度、颜色等进行调整,使图像更加清晰、鲜艳。
常用的图像增强方法包括直方图均衡化、对比度拉伸等。
2. 图像滤波:通过对图像进行滤波操作,去除噪声、平滑图像或者增强图像的边缘等。
常用的图像滤波器包括均值滤波器、中值滤波器、高斯滤波器等。
3. 图像分割:将图像分成若干个不同的区域或者对象,以便进一步分析和处理。
常用的图像分割方法包括阈值分割、边缘检测等。
4. 特征提取:提取图像中的特征以描述图像的内容。
常用的特征包括边缘、纹理、形状等。
特征提取可以通过使用滤波器、边缘检测算法等实现。
三、图像识别和处理的常见算法在图像识别和处理领域,有许多经典的算法被广泛应用。
以下是其中一些常见的算法:1. SIFT算法:尺度不变特征转换(Scale-Invariant Feature Transform,SIFT)是一种用于图像特征提取和匹配的算法。
摄像机标定原理及源码

摄像机标定原理及源码一、摄像机标定原理1.1相机模型在进行摄像机标定之前,需要了解相机模型。
常用的相机模型是针孔相机模型,它假设光线通过小孔进入相机进行成像,形成的图像符合透视投影关系。
针孔相机模型可以通过相机内部参数和外部参数来描述。
1.2相机内部参数相机内部参数主要包括焦距、光心坐标等信息,可以通过相机的标定板来获取。
标定板上通常有已知尺寸的标定点,通过计算图像中的标定点坐标和实际世界中的标定点坐标之间的关系,可以求解出相机的内部参数。
1.3相机外部参数相机外部参数主要包括相机在世界坐标系中的位置和姿态信息。
可以通过引入已知的点和相机对这些点的投影来求解相机的外部参数。
也可以通过运动捕捉系统等设备获取相机的外部参数。
1.4标定算法常用的摄像机标定算法有张正友标定法、Tsai标定法等。
其中,张正友标定法是一种简单和广泛使用的标定方法。
该方法通过对标定板上的角点进行提取和匹配,利用通用的非线性优化算法(如Levenberg-Marquardt算法)最小化像素坐标与世界坐标的重投影误差,从而求解出相机的内部参数和外部参数。
二、摄像机标定源码下面是使用OpenCV实现的摄像机标定源码:```pythonimport numpy as npimport cv2#棋盘格尺寸(单位:毫米)square_size = 25#棋盘内角点个数pattern_size = (9, 6)#获取标定板角点的世界坐标objp = np.zeros((np.prod(pattern_size), 3), dtype=np.float32) objp[:, :2] = np.mgrid[0:pattern_size[0],0:pattern_size[1]].T.reshape(-1, 2) * square_sizedef calibrate_camera(images):#存储角点的世界坐标和图像坐标objpoints = []imgpoints = []for img in images:gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#查找角点ret, corners = cv2.findChessboardCorners(gray, pattern_size, None)if ret:objpoints.append(objp)#亚像素精确化criteria = (cv2.TERM_CRITERIA_EPS +cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)imgpoints.append(corners2)#标定相机ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)return ret, mtx, dist, rvecs, tvecs#读取图像images = []for i in range(1, 21):img = cv2.imread(f'image_{i}.jpg')images.append(img)#相机标定ret, mtx, dist, rvecs, tvecs = calibrate_camera(images)#保存相机参数np.savez('calibration.npz', ret=ret, mtx=mtx, dist=dist, rvecs=rvecs, tvecs=tvecs)```以上代码首先定义了棋盘格尺寸和格子个数,然后定义了函数`calibrate_camera`来进行相机标定。
曝光、影调与照相机的直方图

曝光、影调与照相机的直方图先看图4,光圈系数F=镜头焦距/镜头光圈的直径,直径越大,光圈系数越小,光圈孔面积越大,进的光线越多。
光圈系数F与直径相关所以每级差1.414倍面积才能差一倍。
快门速度、亮度、感光度每级都是两倍的关系。
对于初学者,光圈、快门、感光度的系列数字是要记住的。
好记,就是光圈是1.4倍,其他是两倍的关系。
有的照相机的数据是按1/3或1/2级调整的,只要记住基本差一级的数据就可以了。
他们与AV、TV、BV、SV的对应关系不需要记,用的时候查查就行。
公式EV=AV+TV=B V+SV是要懂的,不然与别人无法交流。
测光测出来的是BV,SV是自己预先选好的,根据BV+SV=EV就确定了EV,再根据EV=AV+TV确定光圈、快门。
对应同一个EV有多种AV、TV的组合,固定一种方式选就是P-程序曝光。
自己选定AV,照相机选TV就是光圈优先。
自己选TV,照相机选AV,就是快门优先。
如果测光决定了BV后SV、AV、TV都让照相机选就是AUTO。
SV感光度一般是预先设定的,此时EV=BV+常数,研究EV、BV相对变化时,可以忽略掉常数部分,所以在感光度SV确定的前提下,经常用EV直接代表BV来讨论问题,比如说亮度范围是5EV,或者说亮度范围EV是5。
至于说是真正的从EV=3到EV=7,还是从EV =5到EV=9,就不关心了。
再比如曝光补偿时经常说+1EV,-2EV等等,此时的1EV实际是使曝光量变化一级的意思。
可以称之为相对EV值。
数码照相机记录的不是景物的亮度值,而是BV值,亮度值和BV是对数关系。
这一点与传统照相机一样,因为这种关系不是由照相机决定的,是由人眼的视神经传导规律决定的。
数码照相机记录BV值后生成的数据不是线性关系,而是如图3的曲线关系,这一点与传统照相机的胶片密度曲线有些相似。
在图3中用相对EV来代替BV的变化范围。
横轴的0是照相机的标准测光点的亮度值,1是亮度两倍,2是亮度4倍。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
题目:图像的基本处理班级:2011级软件2班姓名:刘磊磊时间:20130907摘要:随着数字化与多媒体时代的来临,数字图像处理已经成为必备的基础知识。
全国各大专院校的计算机、电子、通信、医学、光学及许多相关专业都开设了与数字图像预处理相关的课程。
数字图像二值化是图像预处理中的一项重要技术,其在模式识别、光学字符识别、医学成像等方面都有着重要应用。
本论文主要为大家介绍24位真彩图像的灰度、二值处理以及图像的一些简单的打开和保存和如何画直方图,还有一些通过这次小学期学到的一些知识。
关键字:灰度处理,二值化图像的打开void CText1Dlg::ShowPic(){if(m_path =="") //判断图片路径是否存在{return;}hwnd = GetDlgItem(IDC_pic);hDesDC = hwnd->GetDC()->m_hDC;hSrcDC = CreateCompatibleDC(hDesDC);hBitmap=(HBITMAP)LoadImage(AfxGetInstanceHandle(),m_path,IMAGE_BITMAP,0,0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);GetObject(hBitmap, sizeof(BITMAP), &bm);SelectObject(hSrcDC, hBitmap);hwnd->GetClientRect(&rect);::SetStretchBltMode(hDesDC,COLORONCOLOR);::StretchBlt(hDesDC, rect.left, rect.top, rect.right, rect.bottom, hSrcDC,0, 0, bm.bmWidth, bm.bmHeight,+SRCCOPY);UpdateData(false);}void CText1Dlg::Onopenpicture() //打开图像{// TODO: Add your control notification handler code hereinum = 1;CFileDialog dlg(TRUE,"bmp",".bmp",OFN_HIDEREADONL Y,"BMP Files(*.jpg)|*.bmp||");//设置所能打开图像的格式// CFileDialog dlg(TRUE,"jpg",".jpg",OFN_HIDEREADONL Y,"JPG Files(*.bmp)|*.jpg||");这是jpg图像的打开方式if(dlg.DoModal() != IDOK) // dlg_jpg.DoModal(){return;}m_path = dlg.GetPathName(); //获得图片路径UpdateData(false); //更新路径公共变量ShowPic(); //调用显示图片函数}图像的保存我的方法是先选择需要保存的图片并且这张图片是已经命名的,然后选择路径,最后用CopyFile(“原始图像全名包括扩展名”,“保存的全名包括路径+新的命名+扩展名”,false)就OK了。
下面是代码:void CForm::Onsaveroud(){// TODO: Add your control notification handler code hereCString strFolderPath="";TCHAR szPath[_MAX_PA TH];BROWSEINFO bi;bi.hwndOwner = GetSafeHwnd();bi.pidlRoot = NULL;bi.lpszTitle = _T("选择文件夹");bi.pszDisplayName = szPath;bi.ulFlags = BIF_RETURNONL YFSDIRS;bi.lpfn = NULL;bi.lParam = NULL;LPITEMIDLIST pItemIDList = SHBrowseForFolder(&bi);if(pItemIDList){if(SHGetPathFromIDList(pItemIDList,szPath)){strFolderPath = szPath;}// 防止内存泄露,要使用IMalloc接口IMalloc* pMalloc;if( SHGetMalloc(&pMalloc) != NOERROR ){TRACE(_T("无法取得外壳程序的IMalloc接口\n"));}pMalloc->Free(pItemIDList);if(pMalloc)pMalloc->Release();}ScanDiskFile(strFolderPath);}void CForm::ScanDiskFile(CString& strPath){CFileFind find;CString strTemp = strPath;CString strDirectory = strPath + _T("\\") + _T("\\*.*");CString strFile;BOOL IsFind = find.FindFile(strDirectory);IsFind=find.FindNextFile();// 如果是"." 则不扫描if(find.IsDots()){}// 如果是是目录,继续扫描此目录elseif(find.IsDirectory()){strFile = find.GetFileName();strTemp = strTemp ;//+ _T("\\") + strFile;//ScanDiskFile(strTemp);}m_path=strTemp;//m_path就是所要保存图片的路径UpdateData(false);find.Close();}彩色图像的灰度处理:图像灰度处理就是把各个像素点的R,G,B值设置为同一个值,当然要根据图像来取值。
void CText1Dlg::Oncolortogray() //彩色转换灰度{// TODO: Add your control notification handler code here// m_dwOperation = IMAGE_Text1_color_grayed_out;UpdateData();CString str;if(inum == 1)//判别是否是从其他路径读取{m_sourcefile = m_path;//m_sourcefile 是所要处理的彩色图片的路径及全名m_targetfile = m_path+"gray.bmp";//m_targetfile是处理过的图片的路径及全名str = m_targetfile;}m_sourcefile = CStimes;m_targetfile = "gray.bmp";str = m_targetfile;if(m_sourcefile == "" || m_targetfile == "")return;FILE *sourcefile,*targetfile;//位图文件头和信息头BITMAPFILEHEADER sourcefileheader,targetfileheader;BITMAPINFOHEADER sourceinfoheader,targetinfoheader;memset(&targetfileheader,0,sizeof(BITMAPFILEHEADER));memset(&targetinfoheader,0,sizeof(BITMAPINFOHEADER));sourcefile=fopen(m_sourcefile,"rb");fread((void*)&sourcefileheader,1,sizeof(BITMAPFILEHEADER),sourcefile);//提取原图文件头if(sourcefileheader.bfType!=0x4d42){fclose(sourcefile);MessageBox("原图象不为BMP图象!");return;}fread((void*)&sourceinfoheader,1,sizeof(BITMAPINFOHEADER),sourcefile);//提取文件信息头if(sourceinfoheader.biBitCount!=24){fclose(sourcefile);MessageBox("原图象不为24位真彩色!");return;}if(sourceinfoheader.biCompression!=BI_RGB){fclose(sourcefile);MessageBox("原图象为压缩后的图象,本程序不处理压缩过的图象!");return;}//构造灰度图的文件头targetfileheader.bfOffBits=54+sizeof(RGBQUAD)*256;targetfileheader.bfSize=targetfileheader.bfOffBits+sourceinfoheader.biSizeImage/3;targetfileheader.bfReserved1=0;targetfileheader.bfReserved2=0;targetfileheader.bfType=0x4d42;//构造灰度图的信息头,这些都是固定值targetinfoheader.biBitCount=8;targetinfoheader.biSize=40;targetinfoheader.biHeight=sourceinfoheader.biHeight;targetinfoheader.biWidth=sourceinfoheader.biWidth;targetinfoheader.biPlanes=1;targetinfoheader.biCompression=BI_RGB;targetinfoheader.biSizeImage=sourceinfoheader.biSizeImage/3;targetinfoheader.biXPelsPerMeter=sourceinfoheader.biXPelsPerMeter;targetinfoheader.biYPelsPerMeter=sourceinfoheader.biYPelsPerMeter;targetinfoheader.biClrImportant=0;targetinfoheader.biClrUsed=256;//构造灰度图的调色版RGBQUAD rgbquad[256];// color=(RGBMixPlate *)malloc(sizeof(RGBMixPlate)*256);// index=(BYTE *)malloc(sizeof(BYTE)*infohead.readSize);int i,j,m,n,k;for(i=0;i<256;i++){rgbquad[i].rgbBlue=i;rgbquad[i].rgbGreen=i;rgbquad[i].rgbRed=i;rgbquad[i].rgbReserved=0;}targetfile=fopen(m_targetfile,"wb");//写入灰度图的文件头,信息头和调色板信息fwrite((void*)&targetfileheader,1,sizeof(BITMAPFILEHEADER),targetfile);fwrite((void*)&targetinfoheader,1,sizeof(BITMAPINFOHEADER),targetfile);fwrite((void*)&rgbquad,1,sizeof(RGBQUAD)*256,targetfile);BYTE* sourcebuf;BYTE* targetbuf;//这里是因为BMP规定保存时长度和宽度必须是4的整数倍,如果不是则要补足m=(targetinfoheader.biWidth/4)*4;if(m<targetinfoheader.biWidth)m=m+4;n=(targetinfoheader.biHeight/4)*4;if(n<targetinfoheader.biHeight)n=n+4;sourcebuf=(BYTE*)malloc(m*n*3);//读取原图的颜色矩阵信息fread(sourcebuf,1,m*n*3,sourcefile);fclose(sourcefile);targetbuf=(BYTE*)malloc(m*n);BYTE BYcolor[3];// 通过原图颜色矩阵信息得到灰度图的矩阵信息for(i=0;i<n;i++){for(j=0;j<m;j++){for(k=0; k<3; k++)BYcolor[k]=sourcebuf[(i*m+j)*3+k];targetbuf[(i*m)+j]=BYcolor[0]*0.114+BYcolor[1]*0.587+BYcolor[2]*0.299;if(targetbuf[(i*m)+j]>255)targetbuf[(i*m)+j]=255;}}fwrite((void*)targetbuf,1,m*n+1,targetfile);fwrite(&targetinfoheader,1,12,targetfile);fwrite(&targetinfoheader,1,40,targetfile);fclose(targetfile);////////////////////////////////////////////////////preview(IDC_pic,str);//灰度预览}void CText1Dlg::preview(int control, CString CStimes)//预览图片{//conture是所要显示图片的picture控件的ID,CStimes是所要预览的图片的全名(包括扩展名)CString filepath;filepath = CStimes;IStream* stream;IPicture* picture;OLE_XSIZE_HIMETRIC m_width;OLE_YSIZE_HIMETRIC m_height;HGLOBAL hmem;CFile file;file.Open(filepath,CFile::modeReadWrite);DWORD len=file.GetLength();hmem=GlobalAlloc(GMEM_MOVEABLE,len);LPVOID pData=NULL;pData=GlobalLock(hmem);file.ReadHuge(pData,len);file.Close();GlobalUnlock(hmem);CreateStreamOnHGlobal(hmem,TRUE,&stream);OleLoadPicture(stream,len,TRUE,IID_IPicture,(LPVOID*)&picture);picture->get_Height(&m_height);picture->get_Width(&m_width);int width=(int)(240);int height=(int)(225);// int width=(int)(m_width/26.45);// int height=(int)(m_height/26.45);CRect rect1,rect2;GetClientRect(rect1);GetWindowRect(rect2);int x,y;x=rect1.Width()>(width+10)?0:(width+10-rect1.Width());y=rect1.Height()>(height+10)?0:(height+10-rect1.Height());rect2.InflateRect(x/2,y/2);MoveWindow(rect2);CenterWindow();//CDC* pDC=GetDC();CWnd *pi=GetDlgItem(control);//---注意:GetDlgItem是Cwnd类中函数,在此格式是继承;CDC *dc=pi->GetDC(); //picture->Render(dc->m_hDC,0,0,width,height,0,m_height,m_width,-m_height,NULL);pi->ReleaseDC(dc);////}彩色图像的二值化:图像的二值化就是将图像上的每个像素点的灰度值设置为0或255,也就是将整个图变为明显的黑白效果。