TIFF 图像数据提取与处理

怎嘛回事 2014-09-04 03:45:50
不使用其他库!
因为我试了几个库对16位深的图像都是不支持的,都是强制转换成了8位的。
用过TiffLib、 CXimage。这些都不行。


在研究TIFF格式图像,现在能做到读取数据,分析数据头IFH,分析数据目录IFD,分析目录入口DE。
但是关于DE中的条带状数据不会用,也就是DE的Tag= 273,279的使用不会。不知道该怎么用。
另一个就是图像的数据部分不知道结尾在哪里,开头很明显(我知道位置)。
我现在用的TIFF图像分布是:IFH + 图像数据 +IFD
每个文件中只有一个图像。

1.结尾数据难道是在DE中Tag最小值的前面吗?
2.应该按照条状带来提取吗?条状数据怎么提取和使用?

感谢回答,提供思路,最好有资料
...全文
3399 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
段君临 2015-10-19
  • 打赏
  • 举报
回复
引用 8 楼 songlinok 的回复:
[quote=引用 7 楼 Idle_ 的回复:] 根据258和277来看,每个pixel是一个word宽的灰度值,也就是说图片中每像素2字节。那么scanline的宽度就是图片宽度*2 = 3020字节。 根据273来看你图片中包含了428个strip,第一个strip开始于0x4EDA4C。根据279来看每个strip包含4个scanline,那么图片总共可以有1712条scanline但是图片高度只有1710,所以最后一个strip只包含2条scanline. 因为你的strip没有压缩,那么你可以直接从0x4EDA4C处开始读,每3020字节一条scanline(1510像素 )*1710条scanline = 5164200字节 约4.9M图片数据
下午突然脑子开窍了,确实如你所说。 只是“第一个strip开始于0x4EDA4C”应该是“第一个strip的偏移地址开始于0x4EDA4C”呵呵 我使用winhex查看图像数据,根据条带偏移和条带长度进行计算,发现图像中有一些数据是没被使用的,这个是正常的吗?还是所有的数据都会被用上,我有遗漏?[/quote] 偏移量是5167692,这都快到文件末尾了,怎么读取数据呢?
怎嘛回事 2014-09-12
  • 打赏
  • 举报
回复
引用 18 楼 zhao4zhong1 的回复:
不是0x015E就是0x5E01或调色板中对应的色彩。
我这个是TIFF格式的,里面没有调色板。 5E 01 4A 02 3C 03 47 02 DD 02 2B 02 C6 01 E7 02 这个直接就是winhex打开之后看到的图像数据。 你的意思是,灰度值直接就是0x015E?
怎嘛回事 2014-09-11
  • 打赏
  • 举报
回复
#15 说错了。 对于16位深的图像,每个像素点占用2个字节,并非#15上面说的16个字节。 那么5E 01 (这个是第一个条带的前2个字节)怎么转换成灰度值呢?
赵4老师 2014-09-11
  • 打赏
  • 举报
回复
不是0x015E就是0x5E01或调色板中对应的色彩。
zhoujk 2014-09-10
  • 打赏
  • 举报
回复
引用 12 楼 songlinok 的回复:
[quote=引用 10 楼 zhoujk 的回复:] 先把图像加载到图像控件行吗?这样可以从图像控件中提取 IMAGE,然后在上面进行图像数据读取,就很简单了,与格式无关。具体方法可以在我的资源里找
我处理的是16位的灰度图像,直接通过控件获取RGB值然后得到的灰度值是不准确的。 有好的建议吗?谢谢[/quote] 这样做的好处是控件可以打开的所有图像格式都可以用一个方法来读数据,问题是所有的数据都会读成RGB,可能造成不必要的空间浪费。我还真没遇到到数据不准确的问题,你可以试一下先。如果发现不准确的问题告诉我
怎嘛回事 2014-09-10
  • 打赏
  • 举报
回复
因为16位灰度值最大可以是65536 而8位灰度值最大是256. 所以需要<<8 ( 256<<8 == 65536 ) 方便的话可以加我QQ吗?三四五零六二六零九
怎嘛回事 2014-09-10
  • 打赏
  • 举报
回复
引用 14 楼 zhoujk 的回复:
[quote=引用 12 楼 songlinok 的回复:]
[quote=引用 10 楼 zhoujk 的回复:]
先把图像加载到图像控件行吗?这样可以从图像控件中提取 IMAGE,然后在上面进行图像数据读取,就很简单了,与格式无关。具体方法可以在我的资源里找


我处理的是16位的灰度图像,直接通过控件获取RGB值然后得到的灰度值是不准确的。
有好的建议吗?谢谢[/quote]
这样做的好处是控件可以打开的所有图像格式都可以用一个方法来读数据,问题是所有的数据都会读成RGB,可能造成不必要的空间浪费。我还真没遇到到数据不准确的问题,你可以试一下先。如果发现不准确的问题告诉我[/quote]

这个是使用CXimage开源类把tiff图像显示到控件的,我需要计算这个灰度图像中某些像素点的灰度值,
但是因为是显示在控件中的,而且CXimage对tiff 16位深图像不支持,被强转为8位了。

现在直接用的CXimage中的函数得到灰度值,但是这个值需要<<8(左移8位)才能跟16位时该点的灰度值差不多(还是有点差距的)。而通过你提到的直接在控件上获取该点的RGB值,得到的R=G=B(这3个值相等)。通过float gray = 0.3*r+0.59*g+0.11*b;方法转换为灰度值,结果也是有点差距。因为R=G=B,所以float gray = 0.3*r+0.59*g+0.11*b;无具体效果。

所以呢,我现在是想自己来去读tiff源数据,现在已经能把数据按照条带读取出来了,只是现在不知道该怎么把这个数据转化为图像在控件中显示。据我所知需要把这个数据转换成bitmap来显示才行。正在研究这方面资料。

还一个我想问的是,得到tiff源数据,怎么把某一像素点的值转换成灰度值呢?
条带中的数据每个像素点占用16个字节,是说从0开始,前16个字节就是改行的第一个像素点吗?然后依次向后排列?
如果是,那么5E 01 4A 02 3C 03 47 02 DD 02 2B 02 C6 01 E7 02 (这个是第一个条带的前16个字节)怎么转换成灰度值呢?
感谢解惑。
怎嘛回事 2014-09-09
  • 打赏
  • 举报
回复
引用 9 楼 Idle_ 的回复:
你的tiff中包含了DocumentName这个Extension Tag和5个private tags(应该是扫描设备记录的内部信息),没用到的数据应该是这些tag指向的数据。
说的有道理。谢谢
怎嘛回事 2014-09-09
  • 打赏
  • 举报
回复
引用 10 楼 zhoujk 的回复:
先把图像加载到图像控件行吗?这样可以从图像控件中提取 IMAGE,然后在上面进行图像数据读取,就很简单了,与格式无关。具体方法可以在我的资源里找
我处理的是16位的灰度图像,直接通过控件获取RGB值然后得到的灰度值是不准确的。 有好的建议吗?谢谢
怎嘛回事 2014-09-09
  • 打赏
  • 举报
回复
引用 10 楼 zhoujk 的回复:
先把图像加载到图像控件行吗?这样可以从图像控件中提取 IMAGE,然后在上面进行图像数据读取,就很简单了,与格式无关。具体方法可以在我的资源里找
与格式无关? 那么对于灰度图像计算灰度值有影响吗? 按照你的意思,是直接在显示图像的控件中获取像素点的RGB值,然后直接求灰度值就行了吗?不需要用到源图像数据?
zhoujk 2014-09-08
  • 打赏
  • 举报
回复
先把图像加载到图像控件行吗?这样可以从图像控件中提取 IMAGE,然后在上面进行图像数据读取,就很简单了,与格式无关。具体方法可以在我的资源里找
怎嘛回事 2014-09-05
  • 打赏
  • 举报
回复
原始图像 下载链接:http://pan.baidu.com/s/1c02C2Xy
怎嘛回事 2014-09-05
  • 打赏
  • 举报
回复
能不能根据我的这个DE参数,给些具体指点呀。万分感谢啊
怎嘛回事 2014-09-05
  • 打赏
  • 举报
回复
引用 3 楼 Idle_ 的回复:
Orientation(code 274 -- 0x0112)标记不是指明了原点位置吗? 也就是第一条scanline的位置和方向?后续strip只是按这个方向连续而已。
然后PlanarConfiguration(code 284-- 0x011C)又指明了每像素颜色是混合在一起即scanline中每像素都包含rgb component还是分开每种颜色一层--即scanline中只包含一个颜色连续像素然后另一种颜色连续像素。


没有你提到的2中属性。
这个是我的灰度图像属性。
看了你的回答,我的理解是,我可以直接从条带偏移(Tag = 273)处开始读取数据,每次读取(Tag = 279)个字节。 需要读取(Tag=278)次,是这样吗?
可是我还是觉得不太对啊。
阿呆_ 2014-09-05
  • 打赏
  • 举报
回复
Orientation(code 274 -- 0x0112)标记不是指明了原点位置吗? 也就是第一条scanline的位置和方向?后续strip只是按这个方向连续而已。 然后PlanarConfiguration(code 284-- 0x011C)又指明了每像素颜色是混合在一起即scanline中每像素都包含rgb component还是分开每种颜色一层--即scanline中只包含一个颜色连续像素然后另一种颜色连续像素。
怎嘛回事 2014-09-05
  • 打赏
  • 举报
回复
引用 1 楼 Idle_ 的回复:
tiff中的strip就是1~n行scanline根据头中定义的压缩算法压缩而成的,如果没有定义strip包含几行,那么认为每个strip就是一行scanline数据。
我使用的图像属性是: 压缩码 == 1 :未压缩 长:1710 宽:1510 位深:16 11 01 04 00 AC 01 00 00 4C DA 4E 00 273 *图像Strip偏移量0x4EDA4C每个条状数据在文件中的偏移量 17 01 04 00 AC 01 00 00 9C D3 4E 00 279 每个条状数据在文件中的字节数(0x01AC)428*4=1712字节 15 01 03 00 01 00 00 00 01 00 00 00 277 每像素的取样数 1:表示是黑白,灰度 16 01 04 00 01 00 00 00 04 00 00 00 278 每个Strip中的行数 4 1A 01 05 00 01 00 00 00 B0 CF 4E 00 282 x分辨率 300 1B 01 05 00 01 00 00 00 B8 CF 4E 00 283 y分辨率 300 这个是说我的这个图片中有4个Scanline,那么我去数据就直接从偏移地址0x4EDA4C开始读取,读取长度为1712字节*4条扫描行,是这样吗?我看资料说,Sanline之间的排列是无序的,不是安装正序或者倒叙排列的,那么第一个扫面行的地址知道了,其他3个的地址是多少?在哪里看呢? 感谢指导
阿呆_ 2014-09-05
  • 打赏
  • 举报
回复
你的tiff中包含了DocumentName这个Extension Tag和5个private tags(应该是扫描设备记录的内部信息),没用到的数据应该是这些tag指向的数据。
怎嘛回事 2014-09-05
  • 打赏
  • 举报
回复
引用 7 楼 Idle_ 的回复:
根据258和277来看,每个pixel是一个word宽的灰度值,也就是说图片中每像素2字节。那么scanline的宽度就是图片宽度*2 = 3020字节。 根据273来看你图片中包含了428个strip,第一个strip开始于0x4EDA4C。根据279来看每个strip包含4个scanline,那么图片总共可以有1712条scanline但是图片高度只有1710,所以最后一个strip只包含2条scanline. 因为你的strip没有压缩,那么你可以直接从0x4EDA4C处开始读,每3020字节一条scanline(1510像素 )*1710条scanline = 5164200字节 约4.9M图片数据
下午突然脑子开窍了,确实如你所说。 只是“第一个strip开始于0x4EDA4C”应该是“第一个strip的偏移地址开始于0x4EDA4C”呵呵 我使用winhex查看图像数据,根据条带偏移和条带长度进行计算,发现图像中有一些数据是没被使用的,这个是正常的吗?还是所有的数据都会被用上,我有遗漏?
阿呆_ 2014-09-05
  • 打赏
  • 举报
回复
根据258和277来看,每个pixel是一个word宽的灰度值,也就是说图片中每像素2字节。那么scanline的宽度就是图片宽度*2 = 3020字节。 根据273来看你图片中包含了428个strip,第一个strip开始于0x4EDA4C。根据279来看每个strip包含4个scanline,那么图片总共可以有1712条scanline但是图片高度只有1710,所以最后一个strip只包含2条scanline. 因为你的strip没有压缩,那么你可以直接从0x4EDA4C处开始读,每3020字节一条scanline(1510像素 )*1710条scanline = 5164200字节 约4.9M图片数据
阿呆_ 2014-09-04
  • 打赏
  • 举报
回复
tiff中的strip就是1~n行scanline根据头中定义的压缩算法压缩而成的,如果没有定义strip包含几行,那么认为每个strip就是一行scanline数据。

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧