opencv mat读到的图像数据放到BYTE* 中,好像是乱的还是怎么

shiter
人工智能领域优质创作者
博客专家认证
2015-03-26 04:19:00




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);
for (int j = 0; j < width; j++)
{
if (1 == channel)
{
*(p1 + i*step + j) = ps[j];

}
else if (3 == channel)
{
*(p1 + i*step + j*3) = ps[j*3 + 2];
*(p1 + i*step + j*3 + 1) = ps[j*3 + 1];
*(p1 + i*step + j*3 + 2) = ps[j*3];
}
}
}



后面我用的时候一些函数,写好bmp之后出来是图像是倒这的。。。




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");
}


...全文
2297 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
yujie1993 2015-09-26
  • 打赏
  • 举报
回复
能把最终的程序发给我吗,新手,请多多指教
robertbo 2015-03-30
  • 打赏
  • 举报
回复
我简写的没写全,还需要你再扩展一下
shiter 2015-03-27
  • 打赏
  • 举报
回复
引用 17 楼 robertbo 的回复:
对应着你程序中应该修改的地方,下面改了一下,你试试 从int step = (width * 24+31)/8;开始修改: int step = 0; if (1 == channel) { step = (width +3)/4*4; } else if (3 == channel) { step = (width*3 +3)/4*4; } p1 = new BYTE[step*height]; ... int bmp_i = (height-1-i)*step; ... p1[bmp_i+j] = ps[j]; ...
你这么写感觉只复制了三分之一啊。。。
shiter 2015-03-27
  • 打赏
  • 举报
回复
引用 18 楼 worldy 的回复:
[quote=引用 17 楼 robertbo 的回复:] 对应着你程序中应该修改的地方,下面改了一下,你试试 从int step = (width * 24+31)/8;开始修改: int step = 0; if (1 == channel) { step = (width +3)/4*4; } else if (3 == channel) { step = (width*3 +3)/4*4; } ==> step = (width*channel +3)/4*4; 不就可以?
谢谢优化
worldy 2015-03-27
  • 打赏
  • 举报
回复
[quote=引用 17 楼 robertbo 的回复:] 对应着你程序中应该修改的地方,下面改了一下,你试试 从int step = (width * 24+31)/8;开始修改: int step = 0; if (1 == channel) { step = (width +3)/4*4; } else if (3 == channel) { step = (width*3 +3)/4*4; } ==> step = (width*channel +3)/4*4; 不就可以?
robertbo 2015-03-27
  • 打赏
  • 举报
回复
对应着你程序中应该修改的地方,下面改了一下,你试试 从int step = (width * 24+31)/8;开始修改: int step = 0; if (1 == channel) { step = (width +3)/4*4; } else if (3 == channel) { step = (width*3 +3)/4*4; } p1 = new BYTE[step*height]; ... int bmp_i = (height-1-i)*step; ... p1[bmp_i+j] = ps[j]; ...
worldy 2015-03-27
  • 打赏
  • 举报
回复
宽度*24/8
worldy 2015-03-27
  • 打赏
  • 举报
回复
int step = (width * 24+31)/8; step = width*channel; 这个有问题吧,宽度*23/8已经是每行的字节数了,你还乘通道数?
shiter 2015-03-26
  • 打赏
  • 举报
回复
引用 12 楼 worldy 的回复:
范例: 有一张5*5的图片,应该会有25个pixels,但是因为5不是4的倍数所以会显示成: 不是这样的 横向5,需要15字节,不是4的倍数,必须改为16字节 总字节=5*16=80
这个注释是提醒用,我没按这个来
shiter 2015-03-26
  • 打赏
  • 举报
回复
引用 12 楼 worldy 的回复:
范例: 有一张5*5的图片,应该会有25个pixels,但是因为5不是4的倍数所以会显示成: 不是这样的 横向5,需要15字节,不是4的倍数,必须改为16字节 总字节=5*16=80
这块我应该对着呢吧,我现在是opencv把bmp读进来的,想把图像数据写到BYTE里面去,不知道那里有问题
worldy 2015-03-26
  • 打赏
  • 举报
回复
范例: 有一张5*5的图片,应该会有25个pixels,但是因为5不是4的倍数所以会显示成: 不是这样的 横向5,需要15字节,不是4的倍数,必须改为16字节 总字节=5*16=80
shiter 2015-03-26
  • 打赏
  • 举报
回复


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 * 24+31)/8;
	 step = width*channel;
	 //step = step/4*4;
	uchar* ps = NULL;
	
	p1 = new BYTE[width*height*channel+8];
	//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*3) = 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] ;  
			}  
		}  
	}  

shiter 2015-03-26
  • 打赏
  • 举报
回复
引用 9 楼 worldy 的回复:
[quote=引用 7 楼 wangyaninglm 的回复:] 看不懂这个是为何? p2=new BYTE[width*height+8];//为啥要加8? ResImg=p2+8-int(p2)%8;
这个是要让ResImg和8字节的边界对齐吧?[/quote]



我重新写了一下



	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 * 24+31)/8;
	 step = width*channel;
	 //step = step/4*4;
	uchar* ps = NULL;
	
	p1 = new BYTE[width*height*channel+8];
	//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*3) = 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] ;  
			}  
		}  
	}  


结果效果不对啊,后面图片右边还空出来一片。。。
worldy 2015-03-26
  • 打赏
  • 举报
回复
引用 7 楼 wangyaninglm 的回复:
看不懂这个是为何? p2=new BYTE[width*height+8];//为啥要加8? ResImg=p2+8-int(p2)%8;
这个是要让ResImg和8字节的边界对齐吧?
worldy 2015-03-26
  • 打赏
  • 举报
回复
引用 6 楼 wangyaninglm 的回复:
[quote=引用 5 楼 worldy 的回复:] [quote=引用 3 楼 wangyaninglm 的回复:] [quote=引用 2 楼 lx624909677 的回复:] mat图像的左上角,实际是图像的右下角,你要宣传下!
这怎么处理,怎么倒来着。。。 对了再问下,这个:申请空间的补齐是啥情况,我的这边感觉多出来一条 OrgImg=p1+8-int(p1)%8; p2=new BYTE[width*height*3+8]; ResImg=p2+8-int(p2)%8; [/quote] 如果没有记错的话,就是说宽度的字节数是4的倍数[/quote] 奥是不是3个字节3个字节这么一存,但是每一行是4的倍数?[/quote] 正是
shiter 2015-03-26
  • 打赏
  • 举报
回复
看不懂这个是为何? p2=new BYTE[width*height+8];//为啥要加8? ResImg=p2+8-int(p2)%8;
shiter 2015-03-26
  • 打赏
  • 举报
回复
引用 5 楼 worldy 的回复:
[quote=引用 3 楼 wangyaninglm 的回复:] [quote=引用 2 楼 lx624909677 的回复:] mat图像的左上角,实际是图像的右下角,你要宣传下!
这怎么处理,怎么倒来着。。。 对了再问下,这个:申请空间的补齐是啥情况,我的这边感觉多出来一条 OrgImg=p1+8-int(p1)%8; p2=new BYTE[width*height*3+8]; ResImg=p2+8-int(p2)%8; [/quote] 如果没有记错的话,就是说宽度的字节数是4的倍数[/quote] 奥是不是3个字节3个字节这么一存,但是每一行是4的倍数?
worldy 2015-03-26
  • 打赏
  • 举报
回复
引用 3 楼 wangyaninglm 的回复:
[quote=引用 2 楼 lx624909677 的回复:] mat图像的左上角,实际是图像的右下角,你要宣传下!
这怎么处理,怎么倒来着。。。 对了再问下,这个:申请空间的补齐是啥情况,我的这边感觉多出来一条 OrgImg=p1+8-int(p1)%8; p2=new BYTE[width*height*3+8]; ResImg=p2+8-int(p2)%8; [/quote] 如果没有记错的话,就是说宽度的字节数是4的倍数
worldy 2015-03-26
  • 打赏
  • 举报
回复
BYTE *Read24BitBmpFile2Img(const char * filename,int *width,int *height) { ..................... //*width=(BmpHeader.biWidth+3)/4*4; //*height=BmpHeader.biHeight; //size=(*width)*(*height)*3; 这个地方应该有问题,应该是总字节数是4的倍数,不是点数是4的倍数 ==> // Read Image Data *width=BmpHeader.biWidth; *height=BmpHeader.biHeight; int mW=(*width*3+3)/4*4; size=mW*(*height);
shiter 2015-03-26
  • 打赏
  • 举报
回复
引用 2 楼 lx624909677 的回复:
mat图像的左上角,实际是图像的右下角,你要宣传下!
这怎么处理,怎么倒来着。。。 对了再问下,这个:申请空间的补齐是啥情况,我的这边感觉多出来一条 OrgImg=p1+8-int(p1)%8; p2=new BYTE[width*height*3+8]; ResImg=p2+8-int(p2)%8;
加载更多回复(2)

19,472

社区成员

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

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