图片数据
自动化处理图片元数据的Python技巧
自动化处理图片元数据的Python技巧在当今数字化的时代,图片已经成为了我们生活和工作中不可或缺的一部分。
无论是个人的照片库,还是企业的大量图像资源,管理和处理图片元数据都变得至关重要。
Python 作为一种强大而灵活的编程语言,为我们提供了许多工具和技巧来实现图片元数据的自动化处理。
首先,让我们来了解一下什么是图片元数据。
简单来说,图片元数据就是关于图片的信息,例如拍摄时间、地点、相机型号、图片尺寸、作者等等。
这些信息对于图片的管理、分类、搜索和分析都非常有帮助。
```pythonfrom PIL import Imagedef get_image_info(image_path):try:image = Imageopen(image_path)width, height = imagesizeformat = imageformatmode = imagemodeprint(f"图片宽度: {width} 像素")print(f"图片高度: {height} 像素")print(f"图片格式: {format}")print(f"图片模式: {mode}")except Exception as e:print(f"处理图片时发生错误: {e}")image_path ="your_imagejpg"get_image_info(image_path)```上述代码中,我们定义了一个`get_image_info`函数,它接受图片的路径作为参数。
通过`Imageopen`打开图片,然后获取图片的宽度、高度、格式和模式等基本信息。
```pythonimport exifreaddef get_exif_data(image_path):try:with open(image_path, 'rb') as f:tags = exifreadprocess_file(f)for tag in tagskeys():if tag not in ('JPEGThumbnail','TIFFThumbnail','Filename','EXIF MakerNote'):print(f"{tag}:{tagstag}")except Exception as e:print(f"获取元数据时发生错误: {e}")image_path ="your_imagejpg"get_exif_data(image_path)```在这个示例中,我们以二进制模式打开图片文件,然后使用`exifreadprocess_file`获取图片的元数据。
生物图片数据处理教程1——ImageJ
Digital Image Processing is a textbook covering many aspects of digital image
processing, with code examples built with ImageJ.
4
Why ImageJ?
Brightness/Contrast /Color
6
1. Contrast adjustment
Questions: Do the pixel values change after brightness/contrast adjustment? How to compare the signal intensity of different images?
13
Filtering
14
Sharpening
A sharpening filter can be broken down into two steps: It takes a smoothed image, subtracts it from the original image to obtain the "details" of the image, and adds the "details" to the original image. Step 1: Original - Smoothed = "Details"
power” of the gamma value
and then scaled to 8-bits or the min
and max of 16-bit images
9
1. Contrast adjustment (MATLAB)
JPEG 图片碎片数据恢复
今天发了很多技术文章出来!下面我就来发表一份今天才研究的JPEG文件格式的文章!JPEG(Joint Photographic Experts Group)是联合图像专家小组的英文缩写,这个专家组开发的算法称为JPEG算法,并且成为国际上的彩色、灰度、静止图像的第一个国际标准,因此又称为JPEG标准。
JPEG是一个适用范围很广的静态图像数据压缩标准,不仅适用于静止图像的压缩,也常常被用于电视图像序列的帧内图像压缩编码。
目前JPEG专家组开发了两种基本的压缩算法:一种是采用以离散余弦变换DCT为基础的有损压缩算法;另一种是采用以预测技术为基础的无损压缩算法。
使用有损压缩算法时,在压缩比为25:1的情况下,压缩后还原得到的图像和原始图像相比较,非图像专家难以找到它们之间的区别,因此得到了广泛的应用。
例如在V-CD和DVD-Video 电视图像压缩技术中,就使用JPEG的有损压缩算法来取消空间方向上的冗余数据。
以上为广泛参考文献!下面我就发一下我用winhex研究出来的例子:创建一个32*24的红色图形JPEG文件如下图:下面是用Winhex打开的JPEG 文件是以流这里我们称为段和压缩的图像组成的;下面着重介绍段的结构,JPEG文件格式的段总数为30种常见为10种这10种流为名称标记码说明SOI D8 文件头流EOI D9 文件尾流S0F0 C0 帧开始流S0F1 C1 帧开始流DHT C4 定义Huffman表流S0S DA 扫描行开始流DQT DB 定义量化表流DRI DD 定义重新开始间隔流APP0 E0 定义交换格式流COM FE 注释流流的一半结构名称字节数数据说明流标识 1 FF 每个流开始标志流类型 1 D8 类型编码(S0I 文件头流)流长度 2 包括流内容和流长度本身,不包括流开始标识和流类型编码流内容《65533 字节以32*24红色图像JPEG为例子S0I(文件头流)名称字节数值流标识 1 FF流类型 1 D8APP0 (图像识别信息)名称字节数值流标识 1 FF流类型 1 E0流交换格式 5 4A 46 49 46 00 “JFIF“的ASCII 码流主版本号 1 01流次版本号 1 01密度单位 1 01 0=无单位;1=点数/ 英寸;2=点数/厘米X像素密度 2 00 60 水平方向密度Y像素密度 2 00 60 垂直方向密度缩略图X像素 1 00 缩略图水平像素缩略图Y像素 1 00 缩略图垂直像素COM(注释)名称字节数值说明流标识 1 FF流类型 1 FE流长度 2 其值=注释字符的字节数+2 流内容注释字符DQT(定义量化表)名称字节数值说明流类型 1 DB流长度 2 43 其值=3+nS0F0 (图像基本信息)名称字节数值说明流标识 1 FF流类型 1 C0流长度 2 00 11样本精度 1 08 每个样本位数图片高度 2 00 18图片宽度 2 00 20组件数量 1 03 1=灰度图3=YCbCr/YIQ 彩色图4=CMYK彩色图组件ID 1 1=Y, 2=Cb 3=Cr 4=I 5=Q采样系数 1 0-3位:垂直采样系数4-7位:水平采样系数量化表号 1DHT (定义Huffman表)名称字节数值说明流标识 1 FF流类型 1 C4流长度 2 其值=19+nDRI(定义重新开始间隔)名称字节数值说明流标识 1 FF流类型 1 DD流长度 2 04S0S (扫描行开始)名称字节数值说明流标识 1 FF流类型 1 DA流长度 2 00 0C扫描行内组件数量 1 03组件ID 1 1=Y, 2=Cb 3=Cr 4=I 5=Q\ Huffman 表号 1 0-3位;AC表号4-7位; DC 表号E0I(文件尾)名称字节数值流标识FF流编码D9。
BMP图片格式详解
BMP图像格式详解一.简介BMP(Bitmap-File)图形文件是Windows采用的图形文件格式,在Windows环境下运行的所有图象处理软件都支持BMP图象文件格式。
Windows系统内部各图像绘制操作都是以BMP为基础的。
Windows 3.0以前的BMP图文件格式与显示设备有关,因此把这种BMP图象文件格式称为设备相关位图DDB(device-dependent bitmap)文件格式。
Windows 3.0以后的BMP图象文件与显示设备无关,因此把这种BMP图象文件格式称为设备无关位图DIB(device-independent bitmap)格式(注:Windows 3.0以后,在系统中仍然存在DDB位图,象BitBlt()这种函数就是基于DDB位图的,只不过如果你想将图像以BMP格式保存到磁盘文件中时,微软极力推荐你以DIB格式保存),目的是为了让Windows能够在任何类型的显示设备上显示所存储的图象。
BMP位图文件默认的文件扩展名是BMP或者bmp(有时它也会以.DIB或.RLE作扩展名)。
二.BMP格式结构BMP文件的数据按照从文件头开始的先后顺序分为四个部分:◆位图文件头(bmp file header):提供文件的格式、大小等信息◆位图信息头(bitmap information):提供图像数据的尺寸、位平面数、压缩方式、颜色索引等信息◆调色板(color palette):可选,如使用索引来表示图像,调色板就是索引与其对应的颜色的映射表◆位图数据(bitmap data):图像数据区BMP图片文件数据表如下:三.BMP文件头BMP文件头结构体定义如下:typedef struct tagBITMAPFILEHEADER{UINT16 bfType; //2Bytes,必须为"BM",即0x424D 才是Windows位图文件DWORD bfSize; //4Bytes,整个BMP文件的大小UINT16 bfReserved1; //2Bytes,保留,为0UINT16 bfReserved2; //2Bytes,保留,为0DWORD bfOffBits; //4Bytes,文件起始位置到图像像素数据的字节偏移量} BITMAPFILEHEADER;BMP文件头数据表如下:四.BMP信息头BMP信息头结构体定义如下:typedef struct _tagBMP_INFOHEADER{DWORD biSize; //4Bytes,INFOHEADER结构体大小,存在其他版本INFOHEADER,用作区分LONG biWidth; //4Bytes,图像宽度(以像素为单位)LONG biHeight; //4Bytes,图像高度,+:图像存储顺序为Bottom2Top,-:Top2BottomWORD biPlanes; //2Bytes,图像数据平面,BMP存储RGB数据,因此总为1 WORD biBitCount; //2Bytes,图像像素位数DWORD biCompression; //4Bytes,0:不压缩,1:RLE8,2:RLE4DWORD biSizeImage; //4Bytes,4字节对齐的图像数据大小LONG biXPelsPerMeter; //4 Bytes,用象素/米表示的水平分辨率LONG biYPelsPerMeter; //4 Bytes,用象素/米表示的垂直分辨率DWORD biClrUsed; //4 Bytes,实际使用的调色板索引数,0:使用所有的调色板索引DWORD biClrImportant; //4 Bytes,重要的调色板索引数,0:所有的调色板索引都重要}BMP_INFOHEADER;BMP信息头数据表如下:五.BMP调色板BMP调色板结构体定义如下:typedef struct _tagRGBQUAD{BYTE rgbBlue; //指定蓝色强度BYTE rgbGreen; //指定绿色强度BYTE rgbRed; //指定红色强度BYTE rgbReserved; //保留,设置为0 } RGBQUAD;1,4,8位图像才会使用调色板数据,16,24,32位图像不需要调色板数据,即调色板最多只需要256项(索引0 - 255)。
数据分析PPT图片
完整性
数据是否包含了所需的所有信息。
及时性
数据是否及时更新,反映最新情况。
03 数据可视化呈现
CHAPTER
常用数据可视化工具介绍
Tableau 功能强大的数据可视化工具,支 持多种数据源连接,提供丰富的 图表类型和交互式分析功能。
D3.js 一个用于制作数据驱动的文档的 JavaScript库,提供强大的可视 化组件和数据驱动的API。
简洁明了
避免使用过多的图表元素和复杂的视 觉效果,保持设计的简洁明了,突出 重点信息。
一致性
在设计和呈现数据时,保持格式、颜 色、字体等的一致性,有助于提高可 读性和易理解性。
交互性
增加交互功能,如鼠标悬停提示、筛 选、排序等,提高用户体验和数据探 索的便捷性。
实例展示:数据可视化在PPT中的应用
直观地理解数据。
数据挖掘分析
利用算法和模型从大量 数据中挖掘出有用的信
息和模式。
02 数据收集与整理
CHAPTER
数据来源及收集方法
01
02
03
04
问卷调查
设计问卷,通过线上或线下方 式收集数据。
网络爬虫
利用爬虫技术从互联网上抓取 数据。
数据库
从企业内部数据库或公共数据 库中获取数据。
API接口
谢谢
THANKS
优化运营效果
通过对业务数据的分析, 可以发现运营中的问题并 进行优化,提高运营效率 。
数据分析的常用方法
描述性统计分析
对数据进行整理和描述 ,包括数据的中心趋势 、离散程度和分布形态
等。
推断性统计分析
通过样本数据推断总体 特征,包括假设检验和
置信区间等。
海量图片存储方案
海量图片存储方案随着互联网技术的不断发展,图片作为一种重要的信息载体,已经成为人们生活和工作中不可或缺的一部分。
然而,如何高效地存储和管理海量的图片数据成为了一个迫切的问题。
本文将介绍一种可行的海量图片存储方案,以满足大规模图片数据的存储需求。
一、需求分析在提出具体的存储方案之前,我们首先需要对海量图片的存储需求进行分析。
海量图片的存储需求通常具有以下几个特点:1. 存储容量大:海量图片数据通常以TB或PB为单位进行计量,存储容量要求较高。
2. 访问频率低:大部分图片数据在上传之后,其访问频率会显著降低,但是需要保证数据的长期存储和可访问性。
3. 数据安全性:图片数据可能涉及用户隐私、商业机密等重要信息,因此在存储过程中需要确保数据的安全性和隐私保护。
4. 存储效率高:存储海量图片数据时,需要考虑数据的快速存储和高效检索,以满足用户对图片数据的快速访问需求。
二、存储方案基于以上需求分析,我们可以采用以下存储方案来应对海量图片的存储挑战:1. 分布式存储系统:采用分布式存储系统可以提高存储容量和数据并发性能。
通过搭建分布式存储系统,可以将海量图片数据分散存储在多个节点上,形成一个统一的存储集群。
这样既可以提高数据的可靠性和可用性,又可以根据实际需求扩展存储容量。
2. 冷热数据分离:对于访问频率低的图片数据,可以将其归类为冷数据,并采用低成本的存储介质进行存储,如磁带库或冷存储设备。
而对于访问频率高的图片数据,则可以归类为热数据,并采用高性能的存储介质进行存储,如分布式文件系统或高速硬盘阵列。
3. 数据压缩与去重:针对海量图片数据的存储容量问题,可以采用数据压缩和去重技术来减少存储空间的占用。
通过对图片数据进行压缩和去重,可以有效降低存储成本,并提升存储系统的性能。
4. 数据备份与容灾:为了保证海量图片数据的安全性和可靠性,需要进行数据备份和容灾策略的规划。
通过建立数据备份和容灾机制,可以避免数据丢失和不可恢复的风险,确保数据的完整性和可持续性。
冲印照片图片的像素参考数据
冲印照片图片的像素参考数据:(30英寸)30×24 76.20×60.96 (厘米) (32英寸) 32×24 81.28×60.96 (厘米) (36英寸)36×24 91.44×60.96 (厘米) (40英寸) 40×32 101.6×81.28 (厘米) (42英寸) 42×32 106.6×81.28 (厘米) (48英寸) 48×32 121.9×81.28 (厘米)各种证件尺寸:1.身份证 (22mm×32mm)第二代身份证 (26mm×32mm)2.驾驶证 (22mm×32mm)3.黑白小一寸 (22mm×32mm)4.彩色小一寸 (27mm×38mm)5.彩色大一寸 (40mm×55mm)6.普通证件照 (33mm×48mm)数码相机拍摄出来的图片比例是3:4=0.75,而冲印店内的各种规格照片尺寸和比例如下:5寸5×3.5英寸12.7*8.9厘米比例0.706寸6×4英寸15.2*10.2厘米比例0.677寸7×5英寸17.8*12.7厘米比例0.718寸8×6英寸20.3*15.2厘米比例0.75=数码照片比例10寸10×8英寸25.4*20.3厘米比例0.8012寸12×10英寸30.5*20.3厘米比例0.8315寸15×10英寸38.1*25.4厘米比例0.671寸(是指英寸)=2.54cm,彩扩冲印相纸的表现力为300dpi以上(dpi为每英寸多少个点),最低可接受程度大约为200dpi左右。
按照这个方式计算,要求数码图片的像素为:相片尺寸好的效果最低可接受效果5寸5×3.5英寸1600*1200(2.0mega) 1024*7686寸6×4英寸1920*1440(2.8mega) 1200*9007寸7×5英寸2048*1536(3.2mega) 1440*10808寸8×6英寸2400*1800(4.4mega) 1600*120010寸10×8英寸3000*2250(6.8mega) 2048*153612寸12×10英寸3600*2700(9.7mega) 2400*1800(4.4mega)15寸15×10英寸4500*3375(16.0mega) 3000*2250 *mega表示“百万像素”由此可以看出,一架5百万像素的相机,拍摄出来的照片,可以扩印非常好的8寸照片,扩印到12寸也可以达到可接受的效果。
人手图片的数据集(Arpit Mittal, Andrew Zisserman and Phil Torr )_计算机图形_科研数据集
人手图片的数据集(Arpit Mittal, Andrew Zisserman and Phil Torr )(hand dataset(Arpit Mittal, AndrewZisserman and Phil Torr ))数据介绍:We introduce a comprehensive dataset of hand images collected from various different public image data set sources as listed in Table 1. A total of 13050 hand instances are annotated. Hand instances larger than a fixed area of bounding box (1500 sq. pixels) are considered 'big' enough for detections and are used for evaluation. This gives around 4170 high quality hand instances. While collecting the data, no restriction was imposed on the pose or visibility of people, nor was any constraint imposed on the environment. In each image, all the hands that can be perceived clearly by humans are annotated. The annotations consist of a bounding rectangle, which does not have to be axis aligned, oriented with respect to the wrist.关键词:手,图像,验证,培训,测试, hand,image,validation,training,test,数据格式:IMAGE数据详细介绍:H a n d D a t a s e tArpit Mittal, Andrew Zisserman and Phil TorrOverviewWe introduce a comprehensive dataset of hand images collected from various different public image data set sources as listed in Table 1. A total of 13050 hand instances are annotated. Hand instances larger than a fixed area of bounding box (1500 sq. pixels) are considered 'big' enough for detections and are used for evaluation. This gives around 4170 high quality hand instances. While collecting the data, no restriction was imposed on the pose or visibility of people, nor was any constraint imposed on the environment. In each image, all the hands that can be perceived clearly by humans are annotated. The annotations consist of a bounding rectangle, which does not have to be axis aligned, oriented with respect to the wrist.Table 1: Statistics of the hand dataset.* The movie dataset contains frames from the films 'Four weddings and a funeral', 'Apollo 13', 'About a boy' and 'Forrest Gump'. DownloadsPlease cite [1] if you use this dataset.Publications[1] A. Mittal, A. Zisserman, P. H. S. TorrHand detection using multiple proposalsBritish Machine Vision Conference, 2011[2] M. J. Jones and J. M. RehgStatistical color models with application to skin detectionInternational Journal of Computer Vision, 2002AcknowledgementsThis work is funded by the ERC grant VisRec no. 228180 and ONR MURI N00014-07-1-0182.数据预览:点此下载完整数据集。
数据告诉你怎样拍出性感照片
数据告诉你怎样拍出性感照片基于对交友站点“OK丘比特”的用户进行的1100万多次测试结果表明,iPhone用户进行性活动的频繁度是Android用户的2倍。
除此之外,针对不同品牌的相机、不同的参数设置和不同的拍摄时间等等到底哪一项更“性感”,这个研究也得出很多新发现。
看了之后,你也许会对如何拍出好的、吸引人的照片放到你的社交网络得出更直观的结论。
“OK丘比特”网站是互联网上最大和最有趣的交友数据库之一。
本次研究的实验方法是:给出两张有不同变量的照片,让网站用户选择哪一张照片上的人他们更愿意与之交往。
研究用的图片样本多达55.2万张,用来区别的图片信息主要是图片的EXIF数据。
结论最后汇总为图表形式。
测试过程,让用户判断更愿意与谁交往。
图/Gizmodo1、松下>佳能>尼康照相机的品牌出人意料的对照片的吸引程度有很深的影响。
基本上看,不出所料,照相机越好照片就越受欢迎。
这一点在不同年龄段的人群中都有体现。
研究者收集同一个人使用拍照手机、傻瓜相机、高级数码相机分别拍摄的相片,区分度真是一目了然:2、iPhone 用户性活跃度更高一图胜千言。
图表本身已经很能说明问题。
上面的图表针对的是30岁区间的人群。
在全年龄段我们一共找到9785名使用智能手机并标称为某人的性伴侣的用户,结论如下:当然研究全程是匿名的,这个数据只体现出智能手机品牌和性伴侣数目之间的关联。
3、闪光灯让你“显老”7年柔和的光线可以隐藏很多细节——细纹、暗影、不健康的肤色——也就是化妆品们想要消灭的对象。
但是在闪光灯的强光之下,一切都无处遁形。
闪光灯显著地降低了照片中主角吸引人的程度。
根据年龄的轴线平移,闪光灯会让照片上的你“老”7岁。
比如说,用闪光灯的28岁的你的吸引程度只相当于不用闪光灯的35岁的你。
4、突出你自己对背景作模糊处理,突出前方的你,可以让照片变得很艺术。
维基百科上对背景模糊的成像原理的解释。
图/Gizmodo如果你不知道如何在拍照时调整相机的景深,或是根本不能手动调整,你还有秘而不宣的PS大法。
提取图片chart中的数据
提取图⽚中chart 中的数据⼀、介绍⼆、提取思路三、环境说明四、程序实现五、总结需要提取的图⽚示例:本次提取的图⽚数据,是批量的这种图⽚,图⽚说明,存在⼤批量的这种图⽚,其中下⽅的x 标签条⽬个数和顺序,在每张图⽚中都是⼀样的,不同的是左侧的坐标轴刻度可能存在差异。
现在要提取柱状图对应的具体数值。
1.x 轴的label 顺序和个数,在每张图⽚中都是相同的,因此,只需要识别每张图中每个label 对应的数值,按照需要排列即可;2.要识别每个label 对应的柱⼦对应的数值数据,①需要识别到每个柱⼦的⾼度;②需要识别y 坐标轴的⾼度;③需要识别y 坐标轴的⽐例尺;④识别到每个x 轴对应的label 的刻度线位置;3.识别y 坐标轴的⾼度,只需要识别⼤矩形框的左上⻆顶点和右下⻆顶尖,即可算出矩形框的box 宽度和⾼度(⾼度即y 坐标轴的⾼度);4.识别每个x 轴对应的label 的刻度线位置,根据box 宽度与label 的个数,即可得到每个label 对应的位置;5.识别y 坐标轴的⽐例尺,需要识别到坐标轴上⾯的刻度值与对应的刻度线到x 轴底部的⾼度即可算出⼀、介绍⼆、提取思路⽐例尺;6.识别y 坐标轴上的刻度值,采⽤ddddocr 识别,将需要识别的数值对应的局部图⽚通过计算其位置,将其截图下来,然后使⽤ddddocr 进⾏识别;7.识别每个柱⼦对应的⾼度,在每个label 位置作为起点,向上进⾏匹配,有颜⾊的就⼀致匹配,直到出现⽩⾊位置,这个匹配到的⾼度,就是柱⼦的⾼度;需要安装ddddocr 和opencv代码实现:三、环境说明四、程序实现import cv2import numpy as np import os import ddddocr def get_count(arr): ''' ⽤于得到每个x 的label 对应的柱⼦⾼度 ''' c = 0 while True: if arr[c] == 255: c = c + 1 else : break return c def recognize(img_path): ''' ⽤于识别y 坐标轴的刻度值数值 ''' ocr = ddddocr.DdddOcr () with open(img_path, 'rb') as f: img_bytes = f.read () res = ocr.classification (img_bytes) # 在识别的字符串中,容易将0识别为o, res = res.replace ('o', "0") res = res.replace ('O', "0") res = res.replace ('l', "1") res = res.replace ('s', "5") res = res.replace ('S', "5") res = res.replace ('q', "9") return res def extract_data(main_dir, file_name, y_max=None ): # cv2.fli img_path = main_dir.replace ('\\', '/') + '/' + file_name # imgpath = 'images2/⽣物质锅炉.png' # imgpath = 'images2/燃煤锅炉.png' rbg_image = cv2.imread (img_path) # 进⾏灰度处理,减⼩计算量 src = cv2.cvtColor (rbg_image, cv2.COLOR_BGR2GRAY )123456789101112131415161718192021222324252627282930313233343536373839404142434445Python复制代码# 转置之后再上下翻转根据图⽚是横向的还是纵向的,这⾥进⾏适当的转置,翻转等操作 # src = cv2.flip(src.T, flipCode=0) # 进⾏⼆值化处理便于后⾯计算⽐较 retval, dst = cv2.threshold (src, 200, 255, cv2.THRESH_BINARY_INV ) width = dst.shape [1] height = dst.shape [0] # 先找到柱状图的主题框,并使⽤红⾊的线绘制出来 # 1找上下边沿 up = 0 down = 0 for i in range(height): count = list(dst[i, :]).count (255) if up == 0 and count > 1000: up = i elif up != 0 and down == 0 and count > 1000: down = i break # print('up=', up) # print('down=', down) # 找左右边沿 left = 0 right = 0 for i in range(width): count = list(dst[:, i]).count (255) if left == 0 and count > 300: left = i elif left != 0 and right == 0 and count > 300: right = i break # print('left=', left) # print('right=', right) left_top = (left, up) right_bottom = (right, down) # print('left_top=', left_top) # print('right_bottom=', right_bottom) # 绘制外框,验证程序正确性,正确 # cv2.rectangle(src, left_top, right_bottom, (0, 0, 255), 2) box_width = right - left box_height = down - up # 计算每个刻度,绘制线,确认是否计算错误 tick_count = 113 step = box_width / (tick_count + 1) tick_x_pos_list = [] # 每个刻度对应的x 坐标(像素)464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293tick_x_valuescale_list = [] # 每个x 坐标,对应的值所在的⽐例(0-1之间的⼀个⼩数) for i in range(1, tick_count+1): pos = round(i * step) + left tick_x_pos_list.append (pos) cv2.line (src, (pos, down), (pos, up), (0, 0, 255), 1) temp_list = list(dst[up:down, pos]) temp_list.reverse () temp_value = round(get_count(temp_list) / box_height, 3) tick_x_valuescale_list.append (temp_value) # print('tick_value_list=', tick_x_valuescale_list) # print('存在数据的个数=', sum(value > 0 for value in tick_x_valuescale _list)) if not y_max: tick_yheight_list = [] # y 坐标轴刻度对应的位置(刻度线距离x 轴的距离⾼度,单位像素) tick_yvalue_list = [] # y 坐标轴刻度线对应的数值 # 识别左侧y 轴的刻度,⽬的是为了得到yMax for i in range(height): temp_count = list(dst[i, left-3:left]).count (255) if temp_count >= 3: # y 刻度距离x 轴的距离⾼度(单位:像素) tick_yheight_list.append (down - i) # 将刻度对应的左侧数字截图保存为⼀个图⽚,然后调⽤ocr 进⾏识别图中的数字 num_img = src[i-15:i+15, left-30:left-5] temp_file_name = 'temp_'+str(i)+'.jpg' save_path_file = os.path .join ('temp', temp_file_name) cv2.imwrite (save_path_file, num_img) num_str = recognize(save_path_file) num = eval(num_str) tick_yvalue_list.append (num) # print('tick_yheight_list=', tick_yheight_list) # print('tick_yvalue_list=', tick_yvalue_list) y_max = round(tick_yvalue_list[0] / tick_yheight_list[0] * (down - up), 2) print('y_max=', y_max) value_list = [round(value *y_max, 1) for value in tick_x_valuescale_li st] print('value_list=', value_list) # 保存到对应⽬录下的 xxx.txt 中 result_path = os.path .join (main_dir, file_name+".txt") with open(result_path, mode='w') as txt: txt.write ('yMax=' + str(y_max) + '\n' + ', '.join (str(i) for i invalue_list))949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134# 绘制出来 dWindow ('src', cv2.WINDOW_NORMAL ) cv2.resizeWindow ('src', width, height) # width, height cv2.imshow ('src', src) dWindow ('dst', cv2.WINDOW_NORMAL ) cv2.resizeWindow ('dst', width, height) # width, height cv2.imshow ('dst', dst) # 等待关闭 key = cv2.waitKey (0) cv2.destroyAllWindows () # print('-------------------------------全部进⾏跑⼀遍-------------------------------------------------')# # extract_data('images2', '⽣物质锅炉.png')# path = 'D:/Users/Administrator/Desktop/按VOCs 污染源分类'# for main_dir, sub_dir_list, sub_file_list in os.walk(path):# for file_name in sub_file_list:# if file_name.endswith('.jpg') or file_name.endswith('.png'):# try:# extract_data(main_dir, file_name)# except:# result_path = (main_dir + '/' + file_name).replace ('\\', '/')# with open('exception.txt', mode='a') as txt:# txt.write(result_path + '\n') print('-------------------------------针对异常的数据再进⾏特殊处理-------------------------------------------------')# extract_data('D:/Users/Administrator/Desktop/按VOCs 污染源分类/溶剂使⽤源/塑料制品制造', '塑料制品制造.png', 21.42)# extract_data('D:/Users/Administrator/Desktop/按VOCs 污染源分类/⽣物质燃烧/秸秆焚烧', '稻草.png', 20.95)# extract_data('D:/Users/Administrator/Desktop/按VOCs 污染源分类/道路移动源/摩托⻋', '国⼆.png', 13.63) # 是正的,在代码⾥⾯不需要翻转extract_data('D:/Users/Administrator/Desktop/按VOCs 污染源分类/道路移动源/摩托⻋', '国⼆.png') # 是正的,在代码⾥⾯不需要翻转# extract_data('D:/Users/Administrator/Desktop/按VOCs 污染源分类/道路移动源/重型柴油⻋', '国五.png', 18.33)# extract_data('D:/Users/Administrator/Desktop/按VOCs 污染源分类/⾮道路移动源', '建筑机械.png', 19.04)# extract_data('D:/Users/Administrator/Desktop/按VOCs 污染源分类/⾮道路移动源', '⻜机.png', 20.53)135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168示例运⾏输出:⽤于程序中各种计算⽤于⼈眼观察程序过程中输出,需要识别的y 刻度值⾃动截图效果识别的每个x 对应label 的柱⼦数值数据针对上⾯还是存在⼏处不⾜之处:五、总结1.在识别y的坐标刻度值中,存在部分图⽚是带有⼩数的值,在程序的ocr识别中,不能有效识别⼩数点,但整批数据中,只有⼏张图⽚存在该问题,识别坐标轴刻度值的⽬的是为了yMax,从⽽得到⽐例尺,针对这种异常数据,采⽤⼈⼯给定ymax,跳过识别过程;2.整个过程达到了提取数据的⽬的,但是其实与图像识别,没多少关系,除了ocr识别坐标轴刻度值以外,只是对图⽚进⾏初步处理,然后进⾏⽐对达到⽬的的;3.坐标横着的个数和顺序是固定了的,如果不固定,就很难操作了;4.横轴的格式,可以通过识别y坐标轴刻度线的⽅式去识别,但是该程序中没有这个进⾏,知晓个数,直接写死在代码中;。
常见图片格式分析-bmp,png
常见图⽚格式分析-bmp,png⼀、bmp图⽚①单⾊位图:每个像素最多可以表⽰2种颜⾊,只需要使⽤长度为1的⼆进制位来表⽰,因此每个像素占1/8byte② 16⾊位图:每个像素最多可以表⽰16种颜⾊,只需要长度为4(2^4=16)的⼆进制表⽰,每个像素占1/2byte③ 256⾊位图:每个像素最多表⽰256种颜⾊,需要长度为8(2^8=256)的⼆进制表⽰,每个像素占1byte④ 24位位图:即RGB三原⾊位图,每个像素占24位,3个byteps:⼀字节(1byte)=8位(8bit)图形的⼤⼩ = 图⽚的总像素*每个像素的⼤⼩,图⽚的总像素 = 图⽚长*⾼bmp图⽚格式:①位图⽂件头bmfh(占14个字节):数据结构如下:typedef struct tagBITMAPFILEHEADER {WORD bfType; //类型名,字符串“BM”,占2个字节,DWORD bfSize; //⽂件⼤⼩,占4个字节WORD bfReserved1; //保留字,占2个字节WORD bfReserved2; //保留字,占2个字节DWORD bfOffBits; //实际位图数据的偏移字节数,即前三个部分长度之和,占4个字节} BITMAPFILEHEADER;②位图信息头bmih(占40个字节)typedef struct tagBITMAPINFOHEADER{DWORD biSize; //指定此结构体的长度,0x28LONG biWidth; //位图宽LONG biHeight; //位图⾼.为正,表⽰从下往上存储,左下⾓是起点。
为负,表⽰从上往下储存,左上⾓是起点 WORD biPlanes; //平⾯数,为1WORD biBitCount //采⽤颜⾊位数,可以是1,2,4,8,16,24,32DWORD biCompression; //压缩⽅式,可以是0,1,2,其中0表⽰不压缩DWORD biSizeImage; //实际位图数据占⽤的字节数LONG biXPelsPerMeter; //X⽅向分辨率LONG biYPelsPerMeter; //Y⽅向分辨率DWORD biClrUsed; //使⽤的颜⾊数,如果为0,则表⽰默认值(2^颜⾊位数)DWORD biClrImportant; //重要颜⾊数,如果为0,则表⽰所有颜⾊都是重要的} BITMAPINFOHEADER;③彩⾊表aColors单⾊位图彩⾊表占8字节16⾊位图彩⾊表占64字节256⾊位图彩⾊表占1024字节⼆、png图⽚png图⽚格式:由8个字节的PNG⽂件署名和数据块组成png⽂件署名域:89 50 4e 47 0d 0a 1a 0a (固定)IHDR数据块:00 00 00 0d(说明IHDR头块长度为13)49 48 44 52(IHDR的hex值)00 00 00 64(图像的宽,这⾥为100像素)00 00 00 4f(图像的⾼,这⾥为79像素)08 表⽰⾊深 02 表⽰颜⾊类型 00 预留 00 预留 00 ⾮隔⾏扫描92 eb f7 f6(CRC校验)※这⾥需要注意的是图像的宽、⾼数据,ctf题⽬经常将修改宽⾼后的图⽚作为题⽬来隐藏信息最后得有个IEND数据块,通常值为 00 00 00 00 49 45 4E 44 AE 42 60 82在IEND块后⾯添加任何的字符都对⽂件的打开造成不了影响,那我们就可以在这⾥藏⼀些数据了。
基于社交网络图片元数据分析的旅游目的地形象测量研究
基于社交网络图片元数据分析的旅游目的地形象测量研究随着社交网络的普及和发展,人们越来越多地通过发布和分享旅游照片来展示自己的旅行经历。
这些照片不仅是记录旅行的重要方式,还能够反映旅游目的地的形象和吸引力。
因此,通过分析社交网络图片的元数据,可以对旅游目的地的形象进行测量和研究。
首先,社交网络图片的元数据包含了丰富的信息,如拍摄时间、地理位置、摄影设备等。
这些信息可以反映出旅游目的地的热门程度、游客的偏好以及目的地的风景等特征。
例如,通过分析图片的拍摄时间可以了解到旅游目的地的旅游季节和游客的数量变化趋势。
通过分析地理位置信息可以知道哪些景点受到游客的青睐,哪些地方是热门的旅游目的地。
通过分析摄影设备信息可以了解到游客对于拍摄旅游照片的重视程度,从而推测目的地的吸引力和美景。
其次,通过对社交网络图片元数据的分析,可以对旅游目的地的形象进行测量。
形象是指人们对于旅游目的地的整体印象和评价。
人们根据自己的旅行经历和他人的分享来形成对旅游目的地的形象。
通过分析社交网络图片的元数据,可以了解游客对旅游目的地的评价和印象。
例如,通过分析图片的标签和描述可以了解到游客对于目的地的评价和赞美之词;通过分析图片的拍摄角度和构图可以了解到游客对于目的地的视觉印象和观赏角度;通过分析图片的人物和活动可以了解到游客在目的地的体验和活动选择。
这些元数据的分析可以帮助研究者了解旅游目的地的形象和特点,并为旅游发展和市场推广提供参考和决策依据。
最后,基于社交网络图片元数据的分析是一种快速、便捷且经济的研究方法。
相比于传统的问卷调查和实地调研,通过分析社交网络图片的元数据可以获取到大量的数据,且数据的获取和分析过程相对简单。
同时,社交网络图片的元数据是真实的、客观的反映了游客的行为和体验,能够更准确地捕捉到旅游目的地的真实形象。
因此,基于社交网络图片元数据的分析是一种有效的方法来测量和研究旅游目的地的形象。
综上所述,基于社交网络图片元数据的分析是一种有效的方法来测量和研究旅游目的地的形象。
基于UGC图片元数据的目的地形象感知以北京为例
基于UGC图片元数据的目的地形象感知以北京为例一、本文概述随着互联网的快速发展,用户生成内容(UGC)已经成为人们获取和分享信息的重要途径。
在旅游领域,UGC图片作为一种直观、生动的信息载体,对于塑造和感知目的地形象起着至关重要的作用。
这些图片不仅包含了丰富的视觉信息,还通过元数据(如标题、描述、标签等)传达了拍摄者的意图和情感。
因此,研究基于UGC图片元数据的目的地形象感知,对于提升旅游目的地的知名度和吸引力具有重要意义。
本文以北京为例,探讨了如何利用UGC图片元数据来感知和分析目的地形象。
我们对UGC图片进行了收集和整理,提取了其中的元数据信息。
然后,通过文本挖掘和图像识别等技术手段,对这些元数据进行了深入分析和挖掘。
在此基础上,我们总结了北京在UGC图片中的形象特征,包括自然景观、历史文化、现代都市等多个方面。
我们还探讨了不同拍摄者(如游客、当地居民、专业摄影师等)对目的地形象的感知差异及其原因。
本文的研究不仅有助于我们更深入地理解UGC图片在目的地形象感知中的作用,还为旅游目的地管理和营销提供了有益的参考。
通过分析UGC图片元数据,旅游目的地可以更好地把握游客的需求和兴趣点,制定更加精准的营销策略。
本文的研究方法和结论也为其他领域的信息分析和形象感知研究提供了一定的借鉴和启示。
二、文献综述随着互联网的快速发展,用户生成内容(UGC)在塑造和传达目的地形象方面扮演着日益重要的角色。
UGC,主要包括用户发布的图片、视频、文字评论等,不仅数量庞大,而且形式多样,为用户提供了丰富的信息来源,同时也为目的地形象研究提供了新的视角。
在目的地形象感知领域,早期的研究主要关注传统媒体如旅游指南、广告等如何塑造和传播目的地形象。
然而,随着社交媒体和UGC 的兴起,越来越多的学者开始关注UGC在目的地形象感知中的作用。
这些研究普遍认为,UGC能够真实反映游客对目的地的感知和体验,为目的地管理者提供了宝贵的市场情报和形象塑造建议。
用OpenCV和OCR识别图片中的表格数据!OpenCV简直太强大了!
⽤OpenCV和OCR识别图⽚中的表格数据!OpenCV简直太强⼤了!在很多时候,我们的数据来源形式是多种多样的,有时候数据(或表格)也会呈现在图⽚中。
那么,我们如何来获取图⽚中的有⽤数据呢?当⼀张图⽚中含有表格数据的时候,我们可以⽤OpenCV识别表格中的直线,然后再⽤OCR技术识别其中的⽂字。
本⽂仅作为如何识别图⽚中的表格的⼀个例⼦,希望能给读者⼀些启⽰。
笔者⽤到的⼯具如下:opencvpyteressactnumpy我们⽤opencv来识别表格中的直线,⽤pyteressact来识别单元格⽂字,⽤numpy做数值处理。
我们要识别的⽰例图⽚(AI.png)如下:⽰例图⽚ AI.png我们分以下⼏步进⾏识别:1. 识别表格中的横线,即分割记录(每⼀⾏)的横线;2. 识别表格中的竖线,即每个列的分割线;3. 找到数据所在的单元格;4. 利⽤pyteressact识别单元格的⽂字。
识别表格中的横线识别横线之前,我们先创建⼀个图⽚表格识别类(ImageTableOCR),如下:# -*- coding: utf-8 -*-import cv2import pytesseractimport numpy as npclass ImageTableOCR(object):# 初始化def __init__(self, ImagePath):# 读取图⽚self.image = cv2.imread(ImagePath, 1)# 把图⽚转换为灰度模式self.gray = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)其中self.image为RGB模块的图⽚,self.gray为灰度模式的图⽚。
接下来,我们识别图⽚中的分割两条记录的横线。
注意到,相邻两条记录之间的颜⾊是不⼀致的,因此,我们利⽤图⽚灰度化后,每⼀⾏像素的平均值的差的绝对值来作为相邻两条记录的分割线,这样就能检测出分割两条记录的横线了。
机器学习算法在图片识别中的应用
机器学习算法在图片识别中的应用随着科技的发展和计算机的智能化程度不断提高,机器学习算法在图像识别领域的应用变得愈加广泛。
但是,要了解机器学习算法在图片识别中的应用,首先需要了解什么是机器学习以及它的运作原理。
机器学习是一种通过编写和设计的算法来使计算机能够从数据中学习、适应和改进的技术。
它的核心思想是基于数据的模型构建,通过对大量数据的学习和分析,使计算机能够从中总结出规律和模式,并实现自主判断和决策。
在图像识别中,机器学习算法可以利用大量的图片数据进行训练,并通过这些训练数据来识别、分类和标记新的图片。
要实现机器学习算法在图片识别中的应用,首先需要有大量的图片数据。
这些图片数据可以包含不同的类别和标记,以便让算法能够根据类别来进行分类识别。
例如,若要训练一个猫狗分类器,就需要一组已标记为猫和狗的图片集合。
在训练数据准备好后,机器学习算法会通过学习这些数据来构建一个模型。
这个模型是通过对数据的分析和比较来总结出的,它能够将不同的图片类别与其对应的特征联系起来。
例如,猫的图片可能具有某些特定的耳朵形状、眼睛颜色等特征,而狗的图片则可能具有不同的特征。
机器学习算法会根据这些特征来建立一个分类模型,以识别新的未标记图片的类别。
要使机器学习算法在图片识别中得到准确的结果,还需要对算法进行调优和完善。
这可以通过调整算法中的参数、增加训练数据的数量和质量、减少噪声等手段来实现。
此外,还可以采用深度学习算法来提高图片识别的准确性。
深度学习是机器学习的分支领域,其核心是构建人工神经网络模型,通过多层次的神经元连接来实现对复杂数据的学习和分析。
深度学习算法在图片识别中的应用可以更加准确地识别和分析图像。
除了分类识别,机器学习算法在图片识别中还可以用于目标检测、图像生成等任务。
例如,目标检测任务是通过机器学习算法来寻找并标记图像中特定对象的位置和边界框,如汽车、行人等。
图像生成任务则是利用机器学习算法来生成新的图像,如自动生成人脸或风景图片等。
PNG图片数据解析
PNG图⽚数据解析PNG是⼀种⾮常流⾏的图⽚格式,它不仅⽀持透明效果,⽽且图⽚数据经过了压缩处理,所以⼴泛⽤于web等应⽤。
PNG的⽂件格式: PNG⽂件中的数据,总是以⼀个固定的8个字节开头: 除此之外,PNG的其他数据都是以数据块的⽅式组织,它们被分为标准数据块和辅助数据块,其中的辅助数据块是可选的。
关键数据块包含我们必须的图⽚信息,我们之后要重点解析的也是关键数据块。
每种数据块的结构: Length:该数据块的中Chunk Data的长度; Chunk Type Code:数据类型,就是指上⾯提到的IHDR,IEND等; Chunk Data:数据区域,如果是IDAT,就表⽰存储的还未解压的图⽚数据; CRC:循环冗余效验码;具体实现:(实现中没有处理png数据中变形的情况,部分头中的宏定义来⾃libpng,实例不具备实⽤性,仅作参考)头⽂件:1 #ifndef __PNG__2#define __PNG__34 #include <stdio.h>5 #include <stdlib.h>6 #include <math.h>7 #include "zlib/zlib.h"89/**10 * 类型标志11*/12#define PNG_FLAG_HEX "89504E470D0A1A0A"1314/**15 * 数据块类型16*/17#define DATA_CHUNK_TYPE_IHDR "IHDR"18#define DATA_CHUNK_TYPE_IDAT "IDAT"19#define DATA_CHUNK_TYPE_IEND "IEND"20#define DATA_CHUNK_TYPE_tEXt "tEXt"21#define DATA_CHUNK_TYPE_iTXt "iTXt"2223/**24 * 过滤⽅式25*/26#define DATA_FILTER_TYPE_DEFAULT 027#define DATA_FILTER_TYPE_ADD_ROW 128#define DATA_FILTER_TYPE_ADD_UP 229#define DATA_FILTER_TYPE_AVERGE 330#define DATA_FILTER_TYPE_PAETH 43132/* color type masks */33#define PNG_COLOR_MASK_PALETTE 134#define PNG_COLOR_MASK_COLOR 235#define PNG_COLOR_MASK_ALPHA 43637/* color types. Note that not all combinations are legal */38#define PNG_COLOR_TYPE_GRAY 039#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)40#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR)41#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)42#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)4344#define RGB_USE_ALPHA(vr, vg, vb, va) \45 (unsigned)(((unsigned)((unsigned char)(vr) * ((unsigned char)(va) + 1)) >> 8) | \46 ((unsigned)((unsigned char)(vg) * ((unsigned char)(va) + 1) >> 8) << 8) | \47 ((unsigned)((unsigned char)(vb) * ((unsigned char)(va) + 1) >> 8) << 16) | \48 ((unsigned)(unsigned char)(va) << 24))4950/**51 * ⼀次解压图⽚数据的限制52*/53#define DECOMPRESSION_MAX_BYTES 81925455/**56 * 数据块信息57*/58 typedef struct _DataChunkHeader59 {60// 数据长度61 unsigned char length[4];62// 数据类型63 unsigned char type[4];64 } DataChunkHeader;6566/**67 * IHDR数据68*/69 typedef struct _IDHRData70 {71 unsigned char width[4];72 unsigned char height[4];73 unsigned char bitDepth[1];74 unsigned char colorType[1];75 unsigned char compressionMethod[1];76 unsigned char filterMethod[1];77 unsigned char interlaceMethod[1];78 } IDHRData;7980/**81 * PNG图⽚类82*/83class PNG84 {85public:86 PNG();87 PNG(const char* filePath);8889 ~PNG();9091int getWindth();92int getHeight();9394/**95 * 获取图⽚宽度96*/97 unsigned char* getImageData();9899private:100int m_width;101int m_height;102103 unsigned char m_bitDepth;104 unsigned char m_colorType;105 unsigned char m_compressionMethod;106 unsigned char m_filterMethod;107 unsigned char m_interlaceMethod;108 unsigned char m_chanels;109110 unsigned char* m_imageData;111112/**113 * 从⽂件加载图⽚数据114*/115bool loadImageDataFromFile(const char* filePath);116117/**118 * 解析数值119*/120int parseNumber(const unsigned char* data, int len);121122/**123 * 解压数据124*/125int decompressData(z_stream* zStream, unsigned char* data, int dataLen, int leftLen, FILE *pFile); 126127/**128 * ⽣成图⽚数据129*/130void generateImageData(unsigned char* data, unsigned long dataLen);131132/**133 * 默认的过滤⽅式134*/135void defaultFilterType(unsigned char* pImageData, unsigned char* pRowData, int rowBytes);136137/**138 * 当前⾏相加的过滤⽅式139*/140void addCurrentRowFilterType(unsigned char* pImageData, unsigned char* pRowData, int rowBytes); 141142/**143 * 前⼀⾏相加的过滤⽅式144*/145void addUpRowFilterType(unsigned char* pImageData, unsigned char* pRowData, int rowBytes); 146147/**148 * 平均的过滤⽅式149*/150void avergeFilterType(unsigned char* pImageData, unsigned char* pRowData, int rowBytes);151152/**153 * paeth的过滤⽅式154*/155void paethFilterType(unsigned char* pImageData, unsigned char* pRowData, int rowBytes);156157/**158 * 解析IHDR数据159*/160void parseIHDRData(DataChunkHeader& dataChunkHeader, FILE* pFile);161162/**163 * 解析IDAT数据164*/165void parseIDATData(DataChunkHeader& dataChunkHeader, FILE* pFile);166167/**168 * 解析IEND数据169*/170void parseIENDData(DataChunkHeader& dataChunkHeader, FILE *pFile);171172/**173 * 解析其他数据174*/175void parseCommonData(DataChunkHeader& dataChunkHeader, FILE *pFile);176 };177178#endifcpp⽂件:1 #include "png.h"2 #include "utils/cUtil.h"3 #include <stdlib.h>45 #include <windows.h>67/**8 * 默认构造函数9*/10 PNG::PNG()11 {12this->m_width = 0;13this->m_height = 0;1415this->m_imageData = 0;16 }1718/**19 * 构造函数20 * @param filePath 图⽚路径21*/22 PNG::PNG(const char *filePath)23 {24this->m_width = 0;25this->m_height = 0;2627this->loadImageDataFromFile(filePath);28 }2930/**31 * 析构函数32*/33 PNG::~PNG()34 {353738/**39 * 从⽂件加载图⽚数据40*/41bool PNG::loadImageDataFromFile(const char* filePath)42 {43 FILE* pFile = fopen(filePath, "rb");44if (!pFile)45return false;4647// 解析PNG标志48char flag[8];49char hexFlag[17];50 fread(flag, 1, 8, pFile);51 toHexStr(flag, 8, hexFlag);52if (strcmp(hexFlag, PNG_FLAG_HEX) != 0)53return false;5455// 解析图⽚数据56 DataChunkHeader dataChunkHeader;57char dataChunkHeaderType[5];58do {59 fread(&dataChunkHeader, 1, sizeof(DataChunkHeader), pFile);6061 memcpy(dataChunkHeaderType, dataChunkHeader.type, 4);62 dataChunkHeaderType[4] = '\0';6364// IHDR65if ( strcmp(dataChunkHeaderType, DATA_CHUNK_TYPE_IHDR) == 0 ) {66this->parseIHDRData(dataChunkHeader, pFile);67 }68// IDAT69else if ( strcmp(dataChunkHeaderType, DATA_CHUNK_TYPE_IDAT) == 0 ) { 70this->parseIDATData(dataChunkHeader, pFile);71 }72// IEND73else if ( strcmp(dataChunkHeaderType, DATA_CHUNK_TYPE_IEND) == 0 ) { 74this->parseIENDData(dataChunkHeader, pFile);75 }76// 其他数据77else {78this->parseCommonData(dataChunkHeader, pFile);79 }80 } while( strcmp(dataChunkHeaderType, DATA_CHUNK_TYPE_IEND) != 0 );8182int i = 1;8384return true;85 }8687/**88 * 解析数值89*/90int PNG::parseNumber(const unsigned char* data, int len)91 {92char localNum[4];9394bool isLittleEndian = checkEndian();95for (int i = 0; i<4; i++) {96char ch;9798if (isLittleEndian) {99if (i <= len-1)100 ch = data[len - 1 - i];101else102 ch = '\0';103 }104else {105if (i <= len-1)106 ch = data[i];107else108 ch = '\0';109 }110 localNum[i] = ch;111 }112113int num;114 memcpy(&num, localNum, 4);115return num;116 }117118/**119 * 解析IHDR数据121void PNG::parseIHDRData(DataChunkHeader& dataChunkHeader, FILE* pFile)122 {123int dataLen = this->parseNumber(dataChunkHeader.length, 4);124125 IDHRData idhrData;126char crc[4];127128 fread(&idhrData, 1, sizeof(IDHRData), pFile);129 fread(crc, 1, 4, pFile);130131this->m_width = this->parseNumber(idhrData.width, 4);132this->m_height = this->parseNumber(idhrData.height, 4);133this->m_bitDepth = this->parseNumber(idhrData.bitDepth, 1);134this->m_colorType = this->parseNumber(idhrData.colorType, 1);135this->m_compressionMethod = this->parseNumber(pressionMethod, 1);136this->m_filterMethod = this->parseNumber(idhrData.filterMethod, 1);137this->m_interlaceMethod = this->parseNumber(idhrData.interlaceMethod, 1);138this->m_chanels = 0;139140switch (this->m_colorType) {141case PNG_COLOR_TYPE_GRAY:142case PNG_COLOR_TYPE_PALETTE:143this->m_chanels = 1;144break;145case PNG_COLOR_TYPE_RGB:146this->m_chanels = 3;147break;148case PNG_COLOR_TYPE_GRAY_ALPHA:149this->m_chanels = 2;150break;151case PNG_COLOR_TYPE_RGB_ALPHA:152this->m_chanels = 4;153break;154default:155this->m_chanels = 0;156break;157 }158 }159160/**161 * 解压数据162*/163int PNG::decompressData(z_stream* zStream, unsigned char* data, int dataLen, int leftLen, FILE *pFile) 164 {165int result = 0;166167int leftBytesCount = leftLen;168int avail_out = -1;169do {170if (zStream->avail_in == 0) {171if (avail_out == 0)172break;173else {174if (leftBytesCount == 0) {175 DataChunkHeader dataChunkHeader;176 fread(&dataChunkHeader, 1, sizeof(DataChunkHeader), pFile);177178int newDataLen = this->parseNumber(dataChunkHeader.length, 4);179 unsigned char* newData = new unsigned char[dataLen + newDataLen];180char crc[4];181182 fread(newData + dataLen, 1, newDataLen, pFile);183 fread(crc, 1, 4, pFile);184 memcpy(newData, data, dataLen);185186 delete data;187 data = newData;188189 zStream->next_in = newData + dataLen;190 zStream->avail_in = newDataLen;191192 dataLen = dataLen + newDataLen;193194return this->decompressData(zStream, data, dataLen, 0, pFile);195 }196 }197198// 导出数据是否超过限制199if (leftBytesCount > DECOMPRESSION_MAX_BYTES)200 zStream->avail_in = DECOMPRESSION_MAX_BYTES;201else202 zStream->avail_in = leftBytesCount;203204 leftBytesCount -= zStream->avail_in;205 }206207if (avail_out > 0)208 zStream->avail_out = avail_out;209else210 zStream->avail_out = m_width * 4 + 1;211212 result = inflate(zStream, Z_NO_FLUSH);213if (result != Z_OK)214break;215216 avail_out = zStream->avail_out;217 } while (zStream->avail_in >= 0);218219return result;220 }221222/**223 * ⽣成图⽚数据224*/225void PNG::generateImageData(unsigned char* data, unsigned long dataLen) 226 {227// ⾏字节数228int rowBytes = this->m_chanels * this->m_width;229230// 初始化图⽚数据231this->m_imageData = new unsigned char[rowBytes * this->m_height];232233 unsigned char* pImageData = this->m_imageData;234 unsigned char* pRowData = data;235236for (int rowIndex = 0; rowIndex < this->m_height; rowIndex++) {237// 过滤类型238 unsigned char filterType = pRowData[0];239240 pRowData += 1;241242switch (filterType) {243// 不需要过滤处理244case DATA_FILTER_TYPE_DEFAULT:245this->defaultFilterType(pImageData, pRowData, rowBytes);246break;247// 当前⾏相加248case DATA_FILTER_TYPE_ADD_ROW:249this->addCurrentRowFilterType(pImageData, pRowData, rowBytes); 250break;251// 和前⼀⾏相加252case DATA_FILTER_TYPE_ADD_UP:253this->addUpRowFilterType(pImageData, pRowData, rowBytes); 254break;255// 求平均256case DATA_FILTER_TYPE_AVERGE:257this->avergeFilterType(pImageData, pRowData, rowBytes);258break;259// Paeth260case DATA_FILTER_TYPE_PAETH:261this->paethFilterType(pImageData, pRowData, rowBytes);262break;263// 类型错误264default:265break;266 }267268 pImageData += rowBytes;269 pRowData += rowBytes;270271char text[100];272 sprintf(text, "filter type:%d, rowIndex:%d \n", filterType, rowIndex);273 OutputDebugString(text);274 }275276int channel = rowBytes / this->m_width;277if (channel == 4) {278 unsigned int *tmp = (unsigned int *)this->m_imageData;279280for (unsigned short i = 0; i < this->m_height; i++) {281for (unsigned int j = 0; j < rowBytes; j+=4) {282 unsigned int offset = i * rowBytes + j;283284 *tmp++ = RGB_USE_ALPHA(285this->m_imageData[offset],286this->m_imageData[offset+1],287this->m_imageData[offset+2],288this->m_imageData[offset+3]289 );290 }291 }292 }293 }294295/**296 * 默认的过滤⽅式297*/298void PNG::defaultFilterType(unsigned char* pImageData, unsigned char* pRowData, int rowBytes)299 {300for (int i = 0; i < rowBytes; i++) {301 *pImageData++ = *pRowData++;302 }303 }304305/**306 * 当前⾏相加的过滤⽅式307*/308void PNG::addCurrentRowFilterType(unsigned char* pImageData, unsigned char* pRowData, int rowBytes) 309 {310for (int i = 0; i < rowBytes; i++) {311if (i == 0) {312 memcpy(pImageData, pRowData, 4);313 i += 3;314 pImageData += 4;315 pRowData += 4;316 }317else {318 *pImageData++ = (unsigned char)(((int)*(pRowData++) + (int)*(pImageData-4)) & 0xFF);319 }320 }321 }322323/**324 * 前⼀⾏相加的过滤⽅式325*/326void PNG::addUpRowFilterType(unsigned char* pImageData, unsigned char* pRowData, int rowBytes) 327 {328for (int i = 0; i < rowBytes; i++) {329 *pImageData++ = (unsigned char)(((int)*(pRowData++) + (int)*(pImageData-rowBytes)) & 0xFF);330 }331 }332333/**334 * 平均的过滤⽅式335*/336void PNG::avergeFilterType(unsigned char* pImageData, unsigned char* pRowData, int rowBytes)337 {338for (int i = 0; i < rowBytes; i++) {339int averge = 0;340341if (i <= 3) {342 averge = ((int)*(pImageData-rowBytes)) / 2;343344 *pImageData++ = (unsigned char)((averge + (int)*(pRowData++)) & 0xFF);345 }346else {347 averge = (((int)*(pImageData-4)) + ((int)*(pImageData-rowBytes))) / 2;348349 *pImageData++ = (unsigned char)((averge + (int)*(pRowData++)) & 0xFF);350 }351 }352 }353354/**355 * paeth的过滤⽅式356*/357int Paeth(int a, int b, int c)358 {359int p = a + b - c;360int pa = abs(p - a);361int pb = abs(p - b);362int pc = abs(p - c);363364int Paeth;365if(pa <= pb && pa <= pc)366 Paeth = a;367else if (pb <= pc)368 Paeth = b;369else370 Paeth = c;371return Paeth ;372 }373void PNG::paethFilterType(unsigned char* pImageData, unsigned char* pRowData, int rowBytes)374 {375for (int i = 0; i < rowBytes; i++) {376if (i <= 3) {377 *pImageData++ = (unsigned char)(((int)*(pRowData++) + (int)*(pImageData-rowBytes)) & 0xFF); 378 }379else {380 unsigned char left = *(pImageData - 4);381 unsigned char up = *(pImageData - rowBytes);382 unsigned char leftUp = *(pImageData - rowBytes - 4);383384int value = Paeth((int)left, (int)up, (int)leftUp);385386 *pImageData++ = (unsigned char)(((int)*(pRowData++) + value) & 0xFF);387 }388 }389 }390391/**392 * 解析IDAT数据393*/394void PNG::parseIDATData(DataChunkHeader& dataChunkHeader, FILE* pFile)395 {396// 解压后的图⽚数据397 unsigned char* imageData = new unsigned char[m_width * m_height * 4];398399int dataLen = this->parseNumber(dataChunkHeader.length, 4);400// 解压前的图⽚数据401 unsigned char* data = new unsigned char[dataLen];402char crc[4];403// 提取数据404 fread(data, 1, dataLen, pFile);405 fread(crc, 1, 4, pFile);406407// 存放临时的解压数据408 unsigned long decompressDataLen = m_width * m_height * 4 + m_height;409 unsigned char* decompressData = new unsigned char[decompressDataLen];410411 z_stream* zStream = new z_stream();412 zStream->next_in = data;413 zStream->next_out = decompressData;414415 inflateInit(zStream);416417// 解压数据418this->decompressData(zStream, data, dataLen, dataLen, pFile);419// ⽣成图⽚数据420this->generateImageData(decompressData, decompressDataLen);421422/*423 int result = 0;424 // 开始解压数据425 int leftBytesCount = dataLen;426 int avail_out = -1;427 do {428 if (zStream->avail_in == 0) {429 if (avail_out == 0)430 break;431 else {432 if (leftBytesCount == 0) {433434 }435 }436437 // 导出数据是否超过限制438 if (leftBytesCount > DECOMPRESSION_MAX_BYTES)439 zStream->avail_in = DECOMPRESSION_MAX_BYTES;440 else441 zStream->avail_in = leftBytesCount;442443 leftBytesCount = dataLen - zStream->avail_in;444 }445446 if (avail_out > 0)447 zStream->avail_out = avail_out;448 else449 zStream->avail_out = m_width * 4 + 1;450451 result = inflate(zStream, Z_NO_FLUSH);452 if (result != Z_OK)453 break;454455 avail_out = zStream->avail_out;456 } while (zStream->avail_in >= 0);457 // 数据解压是否成功458 if (result == Z_STREAM_END) {459 int i = 1;460 }461*/462 }463464/**465 * 解析IEND数据466*/467void PNG::parseIENDData(DataChunkHeader& dataChunkHeader, FILE *pFile)468 {469char crc[4];470 fread(crc, 1, 4, pFile);471 }472473/**474 * 解析其他数据475*/476void PNG::parseCommonData(DataChunkHeader& dataChunkHeader, FILE *pFile)477 {478int dataLen = this->parseNumber(dataChunkHeader.length, 4);479 fseek(pFile, dataLen + 4, SEEK_CUR);480 }481482/**483 * 获取图⽚宽度484*/485 unsigned char* PNG::getImageData()486 {487return this->m_imageData;488 }489490/**491 * 获取图⽚宽度492*/493int PNG::getWindth()494 {495return this->m_width;496 }497498/**499 * 获取图⽚⾼度500*/501int PNG::getHeight()502 {503return this->m_height;504 }如果需要绘制图⽚,可以使⽤opengl库参考代码:1 glViewport(0, 0, winWidth, winHeight);23 glMatrixMode(GL_PROJECTION);4 glLoadIdentity();5 glOrtho(0.0f, winWidth - 1.0, 0.0, winHeight - 1.0, -10.0, 10.0);67 glMatrixMode(GL_MODELVIEW);8 glLoadIdentity();910 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);1112 glEnable(GL_TEXTURE_2D);1314int width = png->getWindth();15int height = png->getHeight();16 unsigned char* data = png->getImageData();1718 GLuint name1;19 glGenTextures(1, &name1);20 glBindTexture(GL_TEXTURE_2D, name1);21 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);22 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);23 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);24 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);25 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,GL_RGBA, GL_UNSIGNED_BYTE, data);26 glBegin(GL_POLYGON);27 glTexCoord2f(1, 1);28 glVertex3d(800, 800, 2);29 glTexCoord2f(0, 1);30 glVertex3d(0, 800, 2);31 glTexCoord2f(0, 0);32 glVertex3d(0, 0, 2);33 glTexCoord2f(1, 0);34 glVertex3d(800, 0, 2);35 glEnd();。
巧用matlab提取图片中的曲线数据(修订版)
利用Matlab提取图片中的数据(修订版)从事科研或者工程的人员在文档撰写过程中,常需要将文献中的曲线与自己的结果对比,为获取原始数据,一种常用的办法是手动描点,即将原始曲线放大然后打印出来,选取一定数量的点,读出其横纵坐标,然后重绘。
对于较为平坦的曲线,这种方法当然可行,但当曲线数量增加,曲线变化复杂,这种方法工作量可想而知。
前段时间由于原始数据丢失,仅剩几十幅图片,本人尝试过手动描点,经历几个小时奋战,实在无法继续,索性转向matlab,借助其强大的数据处理能力,编写了两个GUI的小软件image2data、data_poly提取数据,如今大功告成,遂于大家分享。
2010-12-26yc97463240@2010年编写软件至今,已有一年,平均每个星期都有网友向我索要软件或提出问题,与你们的交流很愉快,为答谢大家对我的鼓励,我决定:1、对本教程作出修改,针对大家容易出现错误的地方作出批注,并在一个月内对程序进行改进。
2、录制视频教程,更加直接的引导大家使用。
最后申明,本教程完全免费,可在百度、豆丁和其他文档分享类网站在线阅览,教程会发布到优酷上,如有需要,直接email索取(一般当天回复)。
2012-03-10yc97463240@本文分三部分:1、数据提取实验演示;2、软件编写要点;3、附录。
关心使用操作的朋友请看第一部分,有兴趣钻研代码的朋友请看第二部分,本软件以功能实现为主,界面和操作方面略有不适,尽请谅解。
1、数据提取演示实验原始数据来源:安华高科技数据手册(HSMP-38XX and HSMP-48XX Series),如图1所示。
目标曲线:提取1MHz频率下的PIN二极管电容与反偏电压之间关系曲线。
图1 包含目标曲线的原始图像实验步骤:Step1:制作jpg图片方法:利用PPT的图片另存功能制作jpg图片,本方法具有普遍性。
首先从pdf中copy图1,即上述包含数据坐标的曲线,然后paste到ppt的空白页面,最后调整图片大小,另存为 figure1.jpg,如图2所示。