代码改变世界

openvc中读取图像访问图像中像元的的方法

2015-04-26 14:52  hxdlgxq  阅读(571)  评论(0编辑  收藏  举报

一、读取图像

1、利用Mat数据结构读取和显示图片

 

#include"cv.h"
#include "highgui.h"
#include<iostream>
using namespace std;
using namespace cv;
int _tmain(int argc, _TCHAR* argv[])
{
   Mat img=imread("./ImageData/sf1.png");//图片的相对路径
    namedWindow("new");
    imshow("new",image);
return 0;
}

2、利用IplImage指针读取并显示图片

IplImage* image=cvLoadImage("./ImageData/Im_49.png");
cvNamedWindow("image",1);
cvShowImage("image",image);

  

二、访问图像中像元的光谱值

按照图像类型可以将图像分为单通道图像(灰度图像)和多通道图像(RGB)

1、通过指针直接访问像元的灰度值

 

a、IplImage访问单通道图像

 1 //读取rgb彩色图像
 2 IplImage* imgTest=cvLoadImage("./ImageData/sf1.jpg");
 3 
 4 
 5 uchar  tcout;
 6 
 7 //创建同样大小的三个单通道图像
 8 IplImage* rImg=cvCreateImage(cvGetSize(imgTest),IPL_DEPTH_8U,1);  
 9 IplImage* gImg=cvCreateImage(cvGetSize(imgTest),IPL_DEPTH_8U,1);  
10 IplImage* bImg=cvCreateImage(cvGetSize(imgTest),IPL_DEPTH_8U,1); 
11 
12 //将rgb彩色分解到三个单通图像中
13 cvSplit(imgTest,rImg,gImg,bImg,NULL);
14 
15 
16 //访问当通道图像rImg
17     for (int i=0;i<rImg->height;i++)
18     {
19         for (int j=0;j<rImg->width;j++)
20         {
21             tcout=((uchar *)(rImg->imageData+i*rImg->widthStep))[j];
22             
23         }
24 
25     }

这其中有一点需要注意访问时的两个for循环中rImg->heighrImg->width的顺序,很有可能写反了出现内存不可访问的问题 ,之前按照网上的程序写老是出现这个问题,修改过后才得以解决(不知道是Opencv版本的问题还是其他原因);问题提示的错误如下图:

 

b、IplImage访问多通道图像

//读取rgb彩色图像
IplImage* imgTest=cvLoadImage("./ImageData/sf1.jpg");

//创建三个单通道图像
IplImage* TImg=cvCreateImage(cvGetSize(imgTest),IPL_DEPTH_8U,1); 
IplImage* TImg1=cvCreateImage(cvGetSize(imgTest),IPL_DEPTH_8U,1);
IplImage* TImg2=cvCreateImage(cvGetSize(imgTest),IPL_DEPTH_8U,1);

//
uchar* dat2=(uchar*)imgTest->imageData;//以指针的形式访问多通道数据
int step=imgTest->widthStep/sizeof(uchar);//图像中每一行的数据长度
int channels=imgTest->nChannels;//图像通道数


for (int i=0;i<temp->height;i++)
	{
		for (int j=0;j<temp->width;j++)
		{
			((uchar *)(TImg->imageData+i*TImg->widthStep))[j]=dat2[i*step+j*channels+0];
			((uchar *)(TImg1->imageData+i*TImg1->widthStep))[j]=dat2[i*step+j*channels+1];
			((uchar *)(TImg2->imageData+i*TImg2->widthStep))[j]=dat2[i*step+j*channels+2];

			
		}

	}

  

 

2、通过cvGet2D()和cvSet2D访问和修改IplImage相应像元值

IplImage* image=cvLoadImage("./ImageData/Im_49.png");

for (int i=0;i<image->height;i++)
	{
		for (int j=0;j<image->width;j++)
		{
			CvScalar s=cvGet2D(image,i,j); 
			
                        s.val[0]>0
			s.val[1]=255;
			s.val[2]=0;
			cvSet2D(image,i,j,s);
			
			
		}
	}

3、Mat 多通道 数据读取或赋值

Mat n = Mat::zeros( 2, 3, CV_32FC3 );
 
int i=0;
int j=0;
 
n.at<Vec3f>(i,j)[0] = 1;
n.at<Vec3f>(i,j)[1] = 2;
n.at<Vec3f>(i,j)[2] = 3;