吐槽:
先贴一个可以在线看RAW格式图片的网站:Photopea | Online Photo Editor
什么迅捷转换器,ADCsee(好像叫这玩意),各种在线转的网站都不好使,目前我发现的就这个在线网站的和PS可以打开RAW图片
RAW图片可真是让人烦啊,搜了很多资料都是在介绍RAW是什么,原理是什么。没有找到其他教程说如何处理RAW原始数据。
正文:
出于工作需要,要将RAW格式的图片直接进行滤波,然后再转为BMP。直接滤波然后转BMP和先转BMP再滤波,肯定是不同的。不过从16位的RAW到8位的BMP肯定会丢失细节。
要操作原始图片数据就要知道RAW图片的存储格式,由哪几部分构成,很可惜,这部分相关资料也没找到。有推荐的可以告诉我,先十分感谢~
只找到了读取RAW图片的字节流文章,也够用了。
需要处理的lena.raw图片的字节流读取:
我拿到的图是纯数据字节流,即全部都是数据,不像BMP有头信息,位图信息之类的,它全是数据
width = 160 (pixel)
height = 120 (pixel)
且是16bit的小端模式存储,图片的大小为160*120*2=38400字节
raw常用的数据格式:RAW8,RAW10,RAW12,什么意思呢?用几位来表示一个像素,RAW8就是用8位表示一个像素,RAW10是用10位表示一个像素,10需要两个字节,多出的6位没用,补0,RAW12也一样
关于下图的数据,会发现是使用的RAW12,因为只使用到了12位,其余4位是0,如下图是截取到的一些数据(PS:不要用notepad打开,notepad查看16进制一般都是有问题的)
---------使用fread读取,截取前一部分数据
一次读取一个字节
22 B CC 9 3E A B0 A B0 A 3E A 3E A B0 A 3E A 5A 9 3E A B0 A CC 9 22 B 22
一次读取两个字节
B22 9CC A3E AB0 AB0 A3E A3E AB0 A3E 95A A3E AB0 9CC B22 B22 C06 A3E B94 A3E AB0 95A
可以发现,读取两个字节时,自动将数据的大小端调整了,如22 B--->B22,那我就不用转大小端了
直接贴代码,代码有注释
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define height 120
#define width 160
typedef unsigned short BYTE;//要读两个字节所以使用unsigned short
int main()
{
FILE *fp = NULL,*fp2 = NULL;
FILE *fpw;
BYTE B[height*width];
BYTE *ptr;
int i,j,m,,x,y;
int flag,temp;
unsigned short pixel[9]={0};
//打开图片
if((fp = fopen( "lena.raw", "rb" )) == NULL)
{
printf("can not open the raw image \n" );
return 0;
}
else
{
printf("read OK\n");
}
// 分配内存并将图像读到一维数组中
ptr = (BYTE*)malloc( width * height * sizeof(BYTE) );
for( i = 0; i < height*width; i++ )
{
fread( ptr, 2, 1, fp );
B[i]= *ptr;
//printf("B[%d] = %X\n",i,B[i]);
ptr++;
}
fclose(fp);
// 这里可以对一维数组中的图像数据进行处理
for(j=1;j<height-1;j++)
{
for(i=1;i<width-1;i++)
{
//将3×3滑动窗口中的所有像素值放入pixel[m]
m=0;
for(y=j-1;y<=j+1;y++)
{
for(x=i-1;x<=i+1;x++)
{
pixel[m]=B[y*width+x];
m=m+1;
}
}
//让一维数组pixel[9]进行降序排列
do
{
flag=0;//循环结束的标志
for(m=0;m<9;m++)
{
if(pixel[m]<pixel[m+1])
{
temp = pixel[m];
pixel[m] = pixel[m+1];
pixel[m+1] = temp;
flag=1;
}//if
}//for
} while (flag==1);
B[width*j+i]=pixel[4];
}
}
// 将处理后的图像数据输出至done.raw
if( ( fpw = fopen( "done.raw", "wb" ) ) == NULL )
{
printf("can not create the done.raw \n");
return 0;
}
for( i = 0; i < height*width; i++ )
{
fwrite( &B[i], 2 , 1, fpw );
//printf("B[%d] = %X\n",i,B[i]);
}
fclose(fpw);//释放指针
return 0;
}
以下就是我要处理的图,滤波后基本看不出效果,因为正常RAW格式的图大小都在几十兆,这个是领导给我的,纯数据的图,38k左右,滤波算法跟另一篇文章C语言-BMP滤波是一毛一样的,想看其他图片滤波效果的可以去看看
别看就这一丢丢内容,对于刚工作的我来说,搞了一个星期呢!
如有出错误欢迎指正!