两种读数据的方法,一个用opencv读的,另一个是自己写的

shiter
人工智能领域优质创作者
博客专家认证
2015-03-27 01:47:24
opencv读出来到BYTE* 里面不知道是不不是自己写错了,有点问题:




string image_name;
cout<<endl<<"输入图像名:";
cin>>image_name;

Mat image_dst;

if (!isRGB)
{
image_dst = imread(image_name,0);
}
else
{
image_dst = imread(image_name,1);
}



if(image_dst.empty())
{
return -1;
} //是否加载成功

imshow(image_name,image_dst);


width = image_dst.cols;
height = image_dst.rows;
int channel = image_dst.channels();
int step = (width * channel+3)/4*4;
//step = width*channel;
//step = step/4*4;
uchar* ps = NULL;

p1 = new BYTE[step*height];
//size_mem = sizeof(p1);

/*这部分逐个像素表示图像。像素是从下到上、从左到右保存的。每个像素使用一个或者多个字节表示。
如果一个图像水平线的字节数不是4的倍数,这行就使用空字节补齐,通常是ASCII码0。

范例: 有一张5*5的图片,应该会有25个pixels,但是因为5不是4的倍数所以会显示成:
xxxxx000 xxxxx000 xxxxx000 xxxxx000 xxxxx000

x代表调色盘的编号 0代表Null_character
*/

for (int i = 0; i < height; i++)
{
ps = image_dst.ptr<uchar>(i);
int bmp_i = height - i;//opencv mat需要反转一下从左下角开始赋值
for (int j = 0; j < width; j++)
{
if (1 == channel)
{
*(p1 + bmp_i*step + j) = ps[j];

}
else if (3 == channel)
{ //按照bgr三通道分别赋值

*(p1 + bmp_i*step +j) = ps[j*3];
*(p1 + bmp_i*step + j*3 + 1) = ps[j*3 + 1];
*(p1 + bmp_i*step + j*3 + 2) =ps[j*3 + 2] ;
}
}
}

BYTE* px;
if(!isRGB)
{
px = Read8BitBmpFile2Img(image_name.c_str(),&width,&height);
}
else
{
px = Read24BitBmpFile2Img(image_name.c_str(),&width,&height);

}

int len = width*height*channel;
int huanhang = width *channel;


FILE *pFile1 = fopen("out_opencv.txt", "w"); // 文件打开方式 如果原来有内容也会销毁
FILE *pFile2 = fopen("out_ori.txt", "w"); // 文件打开方式 如果原来有内容也会销毁

for (int i = 1;i <=len;i++)
{
//fwrite ((int)*(p1+i), 1,1, pFile);
//cout<<(int)*(p1+i)<<"\t";
fprintf(pFile1,"%d\t",(int)*(p1+i));
if (i % (huanhang)==0)
{
fprintf(pFile1,"\r\n");
//cout<<"kk"<<endl;

/*fwrite ("\n", 1,strlen("\n"), pFile);*/

}

}
cout<<"下面是正常的"<<endl;
//fwrite ("hello\n", 1,strlen("hello\n")+1, pFile );
for (int i = 1;i <=len;i++)
{
fprintf(pFile2,"%d\t",(int)*(px+i));

if (i % huanhang==0)
{
fprintf(pFile2,"\r\n");

/*fwrite ("\n", 1,strlen("\n"), pFile);*/

}

}

fclose(pFile1);
fclose(pFile2);
fflush(pFile1);
fflush(pFile2);

c语言读的:




//////////////////////////
// Read a 24 bit bmp File
//////////////////////////
BYTE *Read24BitBmpFile2Img(const char * filename,int *width,int *height)
{
FILE * BinFile;
BITMAPFILEHEADER FileHeader;
BITMAPINFOHEADER BmpHeader;
BYTE *img;
int size;
int Suc=1;

// Open File
*width=*height=0;
if((BinFile=fopen(filename,"rb"))==NULL) return NULL;
// Read Struct Info
if (fread((void *)&FileHeader,1,sizeof(FileHeader),BinFile)!=sizeof(FileHeader)) Suc=-1;
if (fread((void *)&BmpHeader,1,sizeof(BmpHeader),BinFile)!=sizeof(BmpHeader)) Suc=-1;
if (Suc==-1) { fclose(BinFile); return NULL; }
// Read Image Data
*width=(BmpHeader.biWidth+3)/4*4;
*height=BmpHeader.biHeight;
size=(*width)*(*height)*3;
fseek(BinFile,FileHeader.bfOffBits,SEEK_SET);
if ( (img=new BYTE[size+8])!=NULL)
{
//size_mem = sizeof(img);
if(fread(img+8-int(img)%8,sizeof(BYTE),size,BinFile)!=(unsigned int)size)
{
fclose(BinFile);
delete img;
img=NULL;
return NULL;
}
}
fclose(BinFile);
return img;
}





...全文
426 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
worldy 2015-03-29
  • 打赏
  • 举报
回复
OrgImg=p1+8-int(p1)%8; p2=new BYTE[width*height*3+8]; ResImg=p2+8-int(p2)%8; 这数值计算后,会使得图像的起始点发生偏移吧
shiter 2015-03-29
  • 打赏
  • 举报
回复
引用 16 楼 worldy 的回复:
OrgImg=p1+8-int(p1)%8; p2=new BYTE[width*height*3+8]; ResImg=p2+8-int(p2)%8; 这数值计算后,会使得图像的起始点发生偏移吧
膜拜大神,这个我没发现,相当于全部往后平移了1个字节,我还以为bmp通道也是乱的,哎呦,谢谢大神
shiter 2015-03-28
  • 打赏
  • 举报
回复
引用 14 楼 worldy 的回复:
楼那么多,从哪里看去,发链接过来
你说那个?
worldy 2015-03-28
  • 打赏
  • 举报
回复
楼那么多,从哪里看去,发链接过来
shiter 2015-03-28
  • 打赏
  • 举报
回复
引用 11 楼 worldy 的回复:
加waitkey跟那个有什么关系呢?肯定是链接到了一个错误的库的imread版本,但不知道哪错
不用再意这些细节,先帮忙看看,图片边上的细条是啥情况啊,大牛
worldy 2015-03-28
  • 打赏
  • 举报
回复
你的这个问题搞定了,代码不长好好理解一下 using namespace cv; void CCvMFCAppView::OnReadBmp() { // TODO: 在此添加命令处理程序代码 BITMAPFILEHEADER bmpHeader; BITMAPINFOHEADER bmpInfo; long mImgSize; CFile file; CFileDialog dlg(TRUE); if(dlg.DoModal()!=IDOK) return; file.Open(dlg.GetPathName(),CFile::modeRead); file.Read((PVOID)&bmpHeader,sizeof(bmpHeader)); if(bmpHeader.bfType!=0x4d42)return; int l=file.Read((PVOID)&bmpInfo,sizeof(bmpInfo)); if(bmpInfo.biBitCount<24) return; mImgSize=bmpInfo.biSizeImage; PBYTE pBuf=new BYTE[mImgSize]; if(pBuf==NULL)return; file.Seek(bmpHeader.bfOffBits,CFile::begin); l=file.Read(pBuf,mImgSize); int mWideByte= ((bmpInfo.biWidth*bmpInfo.biBitCount +31)&0xffffffe0) /8; ////这部分注释可以解开,直接将位图显示在当前的View里面 //BITMAPINFO biInfo; //biInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); //biInfo.bmiHeader.biClrUsed=DIB_RGB_COLORS; //biInfo.bmiHeader.biCompression= BI_RGB; //biInfo.bmiHeader.biPlanes=1; //biInfo.bmiHeader.biBitCount=bmpInfo.biBitCount; //biInfo.bmiHeader.biSizeImage=0; //biInfo.bmiHeader.biWidth=bmpInfo.biWidth; //biInfo.bmiHeader.biHeight=bmpInfo.biHeight; //biInfo.bmiHeader.biClrImportant=0; //// Specifies the size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps. ////Windows 98/Me, Windows 2000/XP: If biCompression is BI_JPEG or BI_PNG, ////biSizeImage indicates the size of the JPEG or PNG image buffer, respectively. //CDC* pDC=GetDC(); //PBYTE pDib=NULL; //HBITMAP Handle=CreateDIBSection(pDC->m_hDC,&biInfo,DIB_RGB_COLORS,(LPVOID*)&pDib,NULL,0); //if(Handle==0)return; //memmove(pDib,pBuf,mImgSize); // //CDC memDC; //memDC.CreateCompatibleDC(pDC); //HGDIOBJ hObj=memDC.SelectObject(Handle); //pDC->BitBlt(0,0,bmpInfo.biWidth,bmpInfo.biHeight,&memDC,0,0,SRCCOPY); // //memDC.SelectObject(hObj); //::DeleteObject(Handle); //ReleaseDC(pDC); Mat mat(bmpInfo.biHeight,bmpInfo.biWidth, CV_8UC3, Scalar(255,255,1)); int mMatStep=mat.cols*3; PBYTE pData=mat.data+(mat.rows-1)*mMatStep;/*mat.cols*3*/; PBYTE pBufA=pBuf; for (int i=0;i<bmpInfo.biHeight;i++) { memmove(pData,pBufA,mat.step); pBufA+=mWideByte; pData-=mMatStep;/*mat.step*/; } //直接交换指针不可以,两者的位图结构不一样 //uchar* px=mat.data; //mat.data=pBuf; namedWindow("img"); imshow("img",mat); //mat.data=px; delete pBuf; pBuf=NULL; }
worldy 2015-03-28
  • 打赏
  • 举报
回复
加waitkey跟那个有什么关系呢?肯定是链接到了一个错误的库的imread版本,但不知道哪错
shiter 2015-03-28
  • 打赏
  • 举报
回复
引用 8 楼 worldy 的回复:
[quote=引用 5 楼 wangyaninglm 的回复:] [quote=引用 3 楼 worldy 的回复:] LZ的Opencv是用什么版本的?我是2.49,旦imread无法打开文件,只能使用cvLoadImage
2.4.10,比你高一个版本,哈哈,你把版本信息啥的用下面的换下应该就行吧 #include "opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #pragma comment(lib,"opencv_core249d.lib") #pragma comment(lib,"opencv_highgui249d.lib") #pragma comment(lib,"opencv_imgproc249d.lib") [/quote] 试过了,没有的[/quote] 怎么可能,我用的这么基本的函数。。你肯定是没加waitkey()
赵4老师 2015-03-28
  • 打赏
  • 举报
回复
void HexDump(char *buf,int len,int addr) {
    int i,j,k;
    char binstr[80];

    for (i=0;i<len;i++) {
        if (0==(i%16)) {
            sprintf(binstr,"%08x -",i+addr);
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        } else if (15==(i%16)) {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
            sprintf(binstr,"%s  ",binstr);
            for (j=i-15;j<=i;j++) {
                sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
            }
            printf("%s\n",binstr);
        } else {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        }
    }
    if (0!=(i%16)) {
        k=16-(i%16);
        for (j=0;j<k;j++) {
            sprintf(binstr,"%s   ",binstr);
        }
        sprintf(binstr,"%s  ",binstr);
        k=16-k;
        for (j=i-k;j<i;j++) {
            sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
        }
        printf("%s\n",binstr);
    }
}
worldy 2015-03-27
  • 打赏
  • 举报
回复
引用 5 楼 wangyaninglm 的回复:
[quote=引用 3 楼 worldy 的回复:] LZ的Opencv是用什么版本的?我是2.49,旦imread无法打开文件,只能使用cvLoadImage
2.4.10,比你高一个版本,哈哈,你把版本信息啥的用下面的换下应该就行吧 #include "opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #pragma comment(lib,"opencv_core249d.lib") #pragma comment(lib,"opencv_highgui249d.lib") #pragma comment(lib,"opencv_imgproc249d.lib") [/quote] 试过了,没有的
worldy 2015-03-27
  • 打赏
  • 举报
回复
引用 6 楼 wangyaninglm 的回复:
[quote=引用 3 楼 worldy 的回复:] LZ的Opencv是用什么版本的?我是2.49,旦imread无法打开文件,只能使用cvLoadImage
我之前是三通道的顺序搞错了,opencv 我记得是bgr这存的,怎么bmp居然是grb?[/quote] 不会这么奇怪的顺序吧
shiter 2015-03-27
  • 打赏
  • 举报
回复
引用 3 楼 worldy 的回复:
LZ的Opencv是用什么版本的?我是2.49,旦imread无法打开文件,只能使用cvLoadImage
我之前是三通道的顺序搞错了,opencv 我记得是bgr这存的,怎么bmp居然是grb?
shiter 2015-03-27
  • 打赏
  • 举报
回复
引用 3 楼 worldy 的回复:
LZ的Opencv是用什么版本的?我是2.49,旦imread无法打开文件,只能使用cvLoadImage
2.4.10,比你高一个版本,哈哈,你把版本信息啥的用下面的换下应该就行吧 #include "opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #pragma comment(lib,"opencv_core249d.lib") #pragma comment(lib,"opencv_highgui249d.lib") #pragma comment(lib,"opencv_imgproc249d.lib")
shiter 2015-03-27
  • 打赏
  • 举报
回复
重新写了一下,出现了一个小问题,就是,右手边有一条像素不知道怎么没填上。。。


// Retinex.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include "Retinex.h"
//////////////////////////
//  main
//////////////////////////
int main()
{   
	BYTE *OrgImg,*ResImg,*p1,*p2;
	int width,height,i,j,suc,area1,area2,Tsize;
	bool isRGB,ret;
	clock_t t1,t2;
	double emee,ame;
	char ch;
	int *offsetdata=new int[2];
	for(i=0;i<2;i++)
	{
		*(offsetdata+i)=0X80808080;
	}    
	system( "cls" );	
	printf("******中心/环绕Retienx算法******************\n");
	printf("       1.处理灰度图像\n");
	printf("       2.处理彩色图像\n");
	printf("*********************************************\n");
	printf("请选择(1或2): ");	
	do
	{
		cin>>ch; 
	}while( ch != '1' && ch != '2');

	//system ( "cls" );


	if ( ch == '1')
		isRGB=false;
	else if ( ch == '2')
		isRGB=true;
	// open file

	string image_name;
	cout<<endl<<"输入图像名:";
	cin>>image_name;

	Mat image_dst;

	if (!isRGB)
	{
		image_dst = imread(image_name,0);
	}
	else
	{
		image_dst = imread(image_name,1);
	}

	
	
	if(image_dst.empty())
	{
		return -1;
	} //是否加载成功

	imshow(image_name,image_dst);
	

	 width = image_dst.cols;  
	 height = image_dst.rows;  
	int channel = image_dst.channels(); 
	 int step = width * channel* 1;
	uchar* ps = NULL;
	
	p1 = new BYTE[width*height*channel+8];

	for (int i = 0; i < height; i++)  
	{  
		ps = image_dst.ptr<uchar>(i); 
		int bmp_i = height -1 -i;//图片上下倒置
		for (int j = 0; j <width; j++)  
		{  
			if (1 == channel)  
			{  
				*(p1 + i*step + j) = ps[j];  
				
			}  
			else if (3 == channel)  
			{  //opencv的顺序是bgr,bmp本来是grb?
				*(p1 + bmp_i*step + j*3) = ps[j*3 + 1];  //g
				*(p1 + bmp_i*step + j*3 + 1) = ps[j*3 + 2];  //r
				*(p1 + bmp_i*step + j*3 + 2) = ps[j*3];  //b
			}  
		}  
	}  

	BYTE* px;
	

	if(!isRGB)
		px = Read8BitBmpFile2Img(image_name.c_str(),&width,&height);
	else
		px = Read24BitBmpFile2Img(image_name.c_str(),&width,&height);


	int len = width*height*channel;
	int huanhang = width *channel;


	FILE *pFile1 = fopen("out_opencv.txt",     "w"); // 文件打开方式 如果原来有内容也会销毁
	FILE *pFile2 = fopen("out_ori.txt",     "w"); // 文件打开方式 如果原来有内容也会销毁

	for (int i = 1;i <=len;i++)
	{
		fprintf(pFile1,"%d\t",(int)*(p1+i));
		if (i % (huanhang)==0)
		{
			fprintf(pFile1,"\n");
		
		}

	}
	cout<<"下面是正常的"<<endl;

	for (int i = 1;i <=len;i++)
	{
		fprintf(pFile2,"%d\t",(int)*(px+i));

		if (i % huanhang==0)
		{
			fprintf(pFile2,"\n");
		}

	}

	fclose(pFile1);
	fclose(pFile2);
	fflush(pFile1);
	fflush(pFile2);

	if (p1==NULL)
	{  
		printf("*fopen err!\n");
		delete p1;
		return 0;
	}
	if(width%64!=0||height%64!=0)
	{
		cout<<"图像大小需是64的倍数"<<endl;
		delete p1;
		return 0;
	}

	area1=width*height;

	if(!isRGB)
	{
		OrgImg=p1+8-int(p1)%8;	
		p2=new BYTE[width*height+8];
		ResImg=p2+8-int(p2)%8;
		t2=clock();
		GrayImageProcess(OrgImg,width,height,ResImg);
		t1=clock();
		printf("*****灰度图像处理结果******************\n");
		cout<<"运行时间:"<<t1-t2<<"ms"<<endl;
		Measure(ResImg,width,height,emee,ame);
		cout<<"EMEE:"<<emee<<endl;
		suc=Write8BitImg2BmpFile(ResImg,width,height,"result_1.bmp");
	}
	else
	{	
		OrgImg=p1+8-int(p1)%8;	
		p2=new BYTE[width*height*3+8];		
		ResImg=p2+8-int(p2)%8;
		t2=clock();
		ColorImageProcess(OrgImg,width,height,ResImg);
		t1=clock();
		cout<<"运行时间:"<<t1-t2<<"ms"<<endl;
		t2=clock();
		suc=Write24BitImg2BmpFile(ResImg,width,height,"result_1.bmp");
		ColorImageProcess2(OrgImg,width,height,ResImg);
		t1=clock();
		cout<<"运行时间:"<<t1-t2<<"ms"<<endl;
		suc=Write24BitImg2BmpFile(ResImg,width,height,"result_2.bmp");
	}
	if(suc==-1)
	{
		printf("*fwrite err!\n");  
	}

	Mat result1 = imread("result_1.bmp",1);
	Mat result2 = imread("result_2.bmp",1);

	imshow("result1",result1);
	imshow("result2",result2);
	//release mem
	delete p1;
	delete p2;


	waitKey(0);
	return 0;
}




worldy 2015-03-27
  • 打赏
  • 举报
回复
LZ的Opencv是用什么版本的?我是2.49,旦imread无法打开文件,只能使用cvLoadImage
oyljerry 2015-03-27
  • 打赏
  • 举报
回复
是不是API实现有区别,比如大端,小端数据
shiter 2015-03-27
  • 打赏
  • 举报
回复
上个帖子 http://bbs.csdn.net/topics/391004682

19,472

社区成员

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

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