简单的图像处理

参考网址:

http://www.opencv.org.cn/index.php/OpenCV_%E7%BC%96%E7%A8%8B%E7%AE%80%E4%BB%8B%EF%BC%88%E7%9F%A9%E9%98%B5/%E5%9B%BE%E5%83%8F/%E8%A7%86%E9%A2%91%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%AF%BB%E5%86%99%E6%93%8D%E4%BD%9C%EF%BC%89

 

从文件中读入一幅图像,将之反色,然后显示出来。

 

// HelloOpenCV.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <math.h>
#include <cv.h>
#include <highgui.h>
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) 

int main(int argc, _TCHAR* argv[])
{
	IplImage* img = 0; 
	int height,width,step,channels;
	uchar *data;
	int i,j,k; 
 
	const char * imagePath = "C:\\Users\\lenmovo\\Pictures\\Lena.jpg";
	// load an image  
	img=cvLoadImage(imagePath);
	if(!img){
		printf("Could not load image file: %s\n",argv[1]);
		exit(0);
	}
 
	// get the image data
	height    = img->height;
	width     = img->width;
	step      = img->widthStep;
	channels  = img->nChannels;
	data      = (uchar *)img->imageData;
	printf("Processing a %dx%d image with %d channels\n",height,width,channels);

	// create a window
	cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE);
	cvMoveWindow("mainWin", 300, 100);

	// invert the image
	// 相当于 cvNot(img);
	//IplImage *pDstImg = cvCreateImage(cvGetSize(img),img->depth,img->nChannels);
	//cvNot(img, pDstImg);
	for(i=0;i<height;i++) for(j=0;j<width;j++) for(k=0;k<channels;k++)
	  data[i*step+j*channels+k]=255-data[i*step+j*channels+k];
	//for(i=0;i<height;i++)
	//	for(j=0;j<step;j++)
	//		data[i*step+j]=255-data[i*step+j];
 
	// show the image
	//cvShowImage("mainWin", pDstImg );//显示cvNot(img, pDstImg)结果
	cvShowImage("mainWin", img );
 
	// wait for a key
	cvWaitKey(0);
 
	// release the image
	cvReleaseImage(&img );
	cvDestroyWindow("mainWin");
    return 0; 
}



一. 图像类 IplImage的结构:

typedef struct _IplImage
{
int nSize;			/* IplImage大小 */
int ID;				/* 版本 (=0)*/
int nChannels;			/* 大多数OPENCV函数支持1,2,3 或 4 个通道 */
int alphaChannel;			/* 被OpenCV忽略 */
int depth;			/* 像素的位深度,主要有以下支持格式:*/
				/* IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,IPL_DEPTH_16S, */
				/* IPL_DEPTH_32S,IPL_DEPTH_32F 和IPL_DEPTH_64F */
char colorModel[4];		/* 被OpenCV忽略 */
char channelSeq[4];		/* 同上 */
int dataOrder;			/* 0 - 交叉存取颜色通道, 1 - 分开的颜色通道.只有cvCreateImage可以创建交叉存取图像 */
int origin;			/* 图像原点位置: 0表示顶-左结构,1表示底-左结构 */
int align;			/* 图像行排列方式 (4 or 8),在 OpenCV 被忽略,使用 widthStep 代替 */
int width;			/* 图像宽像素数 */
int height;			/* 图像高像素数*/
struct _IplROI *roi;		/* 图像感兴趣区域,当该值非空时,只对该区域进行处理 */
struct _IplImage *maskROI;		/* 在 OpenCV中必须为NULL */
void *imageId;			/* 同上*/
struct _IplTileInfo *tileInfo;	/* 同上*/
int imageSize;			/* 图像数据大小(在交叉存取格式下ImageSize=image->height*image->widthStep),单位字节*/
char *imageData;			/* 指向排列的图像数据 */
int widthStep;			/* 排列的图像行大小,以字节为单位 */
int BorderMode[4];			/* 边际结束模式, 在 OpenCV 被忽略*/
int BorderConst[4];		/* 同上 */
char *imageDataOrigin;		/* 指针指向一个不同的图像数据结构(不是必须排列的),是为了纠正图像内存分配准备的 */
} IplImage;

 

二. 用到的函数:

1. cvLoadImage(imagePath);  用于从文件中读入

img=cvLoadImage(fileName,flag);
 flag: >0 将读入的图像强制转换为一幅三通道彩色图像
       =0 将读入的图像强制转换为一幅单通道灰度图像
       <0 读入的图像通道数与所读入的文件相同.

图像支持的图像格式: BMP, DIB, JPEG, JPG, JPE, PNG, PBM, PGM, PPM, SR, RAS, TIFF, TIF

OpenCV默认将读入的图像强制转换为一幅三通道彩色图像. 不过可以按以下方法修改读入方式:

2. cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE);

int cvNamedWindow( const char* name, int flags=CV_WINDOW_AUTOSIZE );

name 为窗口的名字,用来区分不同的窗口,并被显示为窗口标题。
flags 窗口属性标志。可以选择CV_WINDOW_AUTOSIZE(1)和0两种值。
CV_WINDOW_AUTOSIZE这个标志被设置后, 如果用户不能手动改变窗口大小,窗口大小会自动调整以适合被显示图像(参考cvShowImage)。
0表示以固定的窗口尺寸显示图像。
函数cvNamedWindow创建一个可以放置图像和trackbar的窗口。
被创建的窗口可以通过它们的名字被引用。
如果已经存在这个名字的窗口,这个函数将不做任何事情。

3.cvMoveWindow("mainWin", 300, 100);

void cvMoveWindow( const char* name, int x, int y );
用于设定或修改名为name的窗口在屏幕中的位置。
x 窗口左上角的x坐标。
y 窗口左上角的y坐标。

4.cvShowImage("mainWin", img );

在指定窗口("mainWin")中显示图像(img)。

5.cvWaitKey(0);

此函数试图让程序等待delay ms后在继续运行其后面的语句。
若delay=0,则无限期等待,直到按下键盘任意按键。

6.cvReleaseImage(&img ); 释放图像

7.cvDestroyWindow("mainWin");销毁指定名字的窗口。

8.cvCreateImage(cvGetSize(img),img->depth,img->nChannels);

IplImage* cvCreateImage(CvSize size, int depth, int channels);size: cvSize(width,height);
depth: 像素深度: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,
                 IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F, IPL_DEPTH_64F
channels: 像素通道数. Can be 1, 2, 3 or 4.
各通道是交错排列的. 一幅彩色图像的数据排列格式如下:
b0 g0 r0 b1 g1 r1 ...

9.cvNot(img, pDstImg);

cvNot(const CvArr* src,CvArr* dst) 函数会将src中的每一个元素的每一位取反,然后把结果赋给dst。

补充:IplImageCvMat派生,而CvMatCvArr派生即CvArr -> CvMat -> IplImage

三. 取反操作

for(i=0;i<height;i++)
    for(j=0;j<width;j++)
        for(k=0;k<channels;k++)
            data[i*step+j*channels+k]=255-data[i*step+j*channels+k];

在上面的cvCreateImage函数说明中提到各通道是交错排列的,所以其中k为第k个通道,step = channels*width。
上面代码可以用

for(i=0;i<height;i++)
		for(j=0;j<step;j++)
			data[i*step+j]=255-data[i*step+j];


替换,也就是对各通道不做区分一致处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值