计算机图形图像处理 实验一
来源:互联网 发布:陈坤 厂花 知乎 编辑:程序博客网 时间:2024/05/16 07:01
计算机图形图像实验
- 计算机图形图像实验
- 一 图像处理初步
- opencv安装配置
- 图像读取与显示
- 图像信息
- 二 图像基本运算
- 加减乘除
- 图形相加
- 图形相减
- 图像相乘
- 图像相除
- 图像灰度级变换
- 图像求反
- 图像变换
- 图像平移
- 图像缩放
- 图像旋转
- 直方图均衡化处理
- 加减乘除
- 一 图像处理初步
一. 图像处理初步
1. opencv安装,配置
VS配置opencv时,要修改三个地方,如下图
2.图像读取与显示
//CvArr//CvMat 是CvArr的子类//IplImage 是CvMat的子类,这里使用IplImage读取和显示文件IplImage* img1 = cvLoadImage(imagename1);cvShowImage("title", img);cvWaitKey(0);//释放内存cvReleaseImage(&img1);//销毁窗口cvDestroyWindow("title");
3.图像信息
//宽img->width//高img->height//大小,这个好像与实际大小不太相符,不是很清楚img->size
二. 图像基本运算
1.加减乘除
图形相加
void add() { cout << "图片加法运算" << endl; const char* imagename1 = "1_add.jpg"; const char* imagename2 = "2_add.jpg"; IplImage* img1 = cvLoadImage(imagename1); IplImage* img2 = cvLoadImage(imagename2); //获取两图片的最小宽、最小高 int min_width = min(img1->width, img2->width); int min_height = min(img1->height, img2->height); //cvSetImageROI设置感兴趣区域,在此处进行操作 cvSetImageROI(img1, CvRect(0, 0, min_width, min_height)); cvSetImageROI(img2, CvRect(0, 0, min_width, min_height)); //两图片相加 cvAddWeighted(img1, 0.5, img2, 0.5, 0.0, img1); cvShowImage("图片相加", img1); cvWaitKey(0); //释放内存 cvReleaseImage(&img1); //销毁窗口 cvDestroyWindow("图片相加");}
实验结果:
图形相减
void sub() { cout << "图片减法运算" << endl; const char* imagename1 = "1_sub.jpg"; const char* imagename2 = "2_sub.jpg"; IplImage* img1 = cvLoadImage(imagename1); IplImage* img2 = cvLoadImage(imagename2); int min_width = min(img1->width, img2->width); int min_height = min(img1->height, img2->height); cvSetImageROI(img1, CvRect(0, 0, min_width, min_height)); cvSetImageROI(img2, CvRect(0, 0, min_width, min_height)); cout << "图片一:" << img1->width << " " << img1->height << endl; cout << "图片二:" << img2->width << " " << img2->height << endl; //cvAddWeighted(img1, 0.5, img2, -0.5, 0.0, img1); cvSub(img1, img2, img1); cvShowImage("图片相减", img1); cvWaitKey(0); //释放内存 cvReleaseImage(&img1); //销毁窗口 cvDestroyWindow("图片相减");}
图像相乘
这里用的是二值蒙板图像与原图像相乘,为了实现一定的效果(去除背景),这里并没有直接使用opencv自带的乘法运算。而是对图像进行了遍历。如果二值蒙版图像在某像素处的值小于10,那么就将与图像在相同位置的值设为0,否则的话不变
void mul() { cout << "图片乘法运算" << endl; const char* imagename1 = "1_mul.jpg"; const char* imagename2 = "2_mul.jpg"; IplImage* img1 = cvLoadImage(imagename1); IplImage* img2 = cvLoadImage(imagename2); int min_width = min(img1->width, img2->width); int min_height = min(img1->height, img2->height); //cvSetImageROI(img1, CvRect(0, 0, min_width, min_height)); //cvSetImageROI(img2, CvRect(0, 0, min_width, min_height)); cout << "图片一:" << img1->width << " " << img1->height << endl; cout << "图片二:" << img2->width << " " << img2->height << endl; for (int i = 0; i < min_height; i ++) { uchar* ptr = (uchar*)(img1->imageData + i* img1->widthStep); uchar* ptr2 = (uchar*)(img2->imageData + i* img2->widthStep); for (int j = 0; j < min_width; j++) { if (ptr[3 * j] < 10) ptr2[3 * j] = 0; if (ptr[3 * j + 1] < 10) ptr2[3 * j + 1] = 0; if(ptr[3 *j + 2] < 10) ptr2[3 * j + 2] = 0; /* if (ptr[3 * j] == 0) { ptr2[3 * j] = ptr[3 * j + 1] = ptr[3 * j + 2] = 0; } */ } } //cvMul(img2, img1, img1); cvShowImage("图片相乘", img2); cvWaitKey(0); //释放内存 cvReleaseImage(&img2); //销毁窗口 cvDestroyWindow("图片相乘");}
图像相除
void div() { cout << "图片除法运算" << endl; const char* imagename1 = "2_add.jpg"; const char* imagename2 = "3.jpg"; //const char* imagename1 = "1_mul.jpg"; //const char* imagename2 = "2_mul.jpg"; IplImage* img1 = cvLoadImage(imagename1); IplImage* img2 = cvLoadImage(imagename2); int min_width = min(img1->width, img2->width); int min_height = min(img1->height, img2->height); cvSetImageROI(img1, CvRect(0, 0, min_width, min_height)); cvSetImageROI(img2, CvRect(0, 0, min_width, min_height)); cout << "图片一:" << img1->width << " " << img1->height << endl; cout << "图片二:" << img2->width << " " << img2->height << endl; cvDiv(img2, img1, img2); cvShowImage("图片相除", img2); cvWaitKey(0); //释放内存 cvReleaseImage(&img2); //销毁窗口 cvDestroyWindow("图片相除");}
2.图像灰度级变换
图像求反
void reverse() { cout << "图片求反运算" << endl; const char* imagename = "2_mul.jpg"; IplImage* img = cvLoadImage(imagename); for (int i = 0; i < img->height; i++) { uchar* ptr = (uchar*)(img->imageData + i* img->widthStep); for (int j = 0; j < img->width; j++) { ptr[3 * j] = 255 - ptr[3 * j]; ptr[3 * j + 1] = 255 - ptr[3 * j + 1]; ptr[3 * j + 2] = 255 - ptr[3 * j + i]; } } cvShowImage("图片求反", img); cvWaitKey(0); //释放内存 cvReleaseImage(&img); //销毁窗口 cvDestroyWindow("图片求反");}
3.图像变换
图像平移
void transform() { cout << "图片平移" << endl; const char* imagename = "2_add.jpg"; IplImage* img = cvLoadImage(imagename); int dx, dy; cout << "请输入平移的宽和高, 如:50 50" << endl; cin >> dx >> dy; int height = img->height; int width = img->width; IplImage* res = cvCreateImage(cvSize(width, height), img->depth, img->nChannels); for (int i = 0; i < height; i++) { int pos_x = i + dx; if (pos_x < height && pos_x > -1) { uchar* ptr = (uchar*)(img->imageData + i* img->widthStep); uchar* ptr2 = (uchar*)(res->imageData + pos_x * res->widthStep); for (int j = 0; j < width; j++) { int pos_y = j + dy; if (pos_y < width && pos_y > -1) { ptr2[3 * pos_y] = ptr[3 * j]; ptr2[3 * pos_y + 1] = ptr[3 * j + 1]; ptr2[3 * pos_y + 2] = ptr[3 * j + 2]; } } } } cvShowImage("图片平移", res); cvWaitKey(0); //释放内存 cvReleaseImage(&res); //销毁窗口 cvDestroyWindow("图片平移");}
图像缩放
这里输入图像宽和高的缩放倍数(> 0), 对图像进行放大和缩小
void zoom() { cout << "图片缩放" << endl; const char* imagename = "2_add.jpg"; IplImage* img = cvLoadImage(imagename); float dx, dy; cout << "请输入图片宽和高的放大倍数,如:1 0.5" << endl; cin >> dx >> dy; int height = img->height; int width = img->width; IplImage* res = cvCreateImage(cvSize(width*dx, height*dy), img->depth, img->nChannels); //二维旋转的仿射变换矩阵 float m[6] = {dx, 0, 0, 0, dy, 0}; CvMat M = cvMat(2, 3, CV_32F, m); //变换图像 cvWarpAffine(img, res, &M, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS); cvShowImage("图片缩放", res); cvWaitKey(0); //释放内存 cvReleaseImage(&res); //销毁窗口 cvDestroyWindow("图片缩放");}
图像旋转
图像旋转后,会导致图像显示不全,这里图像旋转后,大小会发生变化,使图片能够显示完全
void rotate() { cout << "图片旋转" << endl; const char* imagename = "2_add.jpg"; IplImage* img = cvLoadImage(imagename); int degree; cout << "请输入图像旋转角度, 如:30" << endl; cin >> degree; double angle = degree * CV_PI / 180.; // 弧度 double sina = sin(angle), cosa = cos(angle); int height = img->height; int width = img->width; int width_rotate = int(height * fabs(sina) + width * fabs(cosa)); int height_rotate = int(width * fabs(cosa) + height * fabs(sina)); cout << width << " " << height << endl; cout << width_rotate << " " << height_rotate << endl; IplImage* res = cvCreateImage(cvSize(width_rotate, height_rotate), img->depth, img->nChannels); //旋转中心 CvPoint2D32f center; center.x = float(width / 2.0); center.y = float(height / 2.0); //二维旋转的仿射变换矩阵 float m[6]; //float m[6]; CvMat M = cvMat(2, 3, CV_32F, m); cv2DRotationMatrix(center, degree, 1, &M); m[2] += (width_rotate - width) / 2; m[5] += (height_rotate - height) / 2; //变换图像,其余值填充用白色 cvWarpAffine(img, res, &M, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll(255)); cvShowImage("图片旋转", res); cvWaitKey(0); //释放内存 cvReleaseImage(&res); //销毁窗口 cvDestroyWindow("图片旋转");}
4.直方图均衡化处理
要求:自己编写函数,不能使用opencv自带函数(虽然我也不知道自带函数是什么…)
直方图均衡化是将原图像通过某种变换,得到一幅图像,整个图像灰度直方图为均匀分布的新图像的方法。
根据个人理解,直方图均衡化处理大致有如下步骤:
- 灰度直方图统计hist[0..L-1]: 图像有L灰度级(L=256,即8位灰度级),统计各个灰度级在图像中出现的次数,之后hist[]/=图像像素。
- 归一化累积直方图t[0..L-1]: 计算方式为t[x] = t[x-1] + s[x]
- 遍历图像,根据t[0..L-1],计算每一点新的像素值: f(x,y) = t[f(x,y)]*L
void equalization() { cout << "直方图均衡化" << endl; const char* imagename = "4.jpg"; IplImage* img = cvLoadImage(imagename); double *hist = new double[256]; double *t = new double[256]; for (int i = 0; i < 256; i++) { hist[i] = 0; t[i] = 0; } for (int i = 0; i < img->height; i++) { uchar* ptr = (uchar*)(img->imageData + i* img->widthStep); for (int j = 0; j < img->width; j++) { hist[ptr[3 * j]]++; hist[ptr[3 * j + 1]]++; hist[ptr[3 * j + 2]]++; } } int result = img->width*img->height*3; t[0] = hist[0]/result; for (int i = 1; i < 256; i++) { t[i] = t[i - 1] + (double)(hist[i]/result); } for (int i = 0; i < img->height; i++) { uchar* ptr = (uchar*)(img->imageData + i* img->widthStep); for (int j = 0; j < img->width; j++) { ptr[3 * j] = t[ptr[3*j]]*255; ptr[3 * j + 1]=t[ptr[3*j + 1]]*255; ptr[3 * j + 2]=t[ptr[3*j + 2]]*255; } } cvShowImage("直方图均衡化", img); cvWaitKey(0); //释放内存 cvReleaseImage(&img); //销毁窗口 cvDestroyWindow("直方图均衡化");}
0 0
- 计算机图形图像处理 实验一
- 计算机图形图像处理 实验二
- 计算机图形图像学实验指导书
- 【杂谈】数学,计算机视觉,图形图像处理
- Atitit.计算机图形图像图片处理原理与概论attilax总结
- 图形图像处理
- 图形图像处理
- 图形图像处理
- Android学习之——图形图像处理(Bitmap、BitmapFactory)(一)
- Android学习之——图形图像处理(Bitmap、BitmapFactory)(一)
- iOS 图形图像处理 一 :位图图像原图修改
- Android学习之Paint图形图像处理(一)
- 数字信号处理实验(一)
- 数字图像处理实验(一)
- 图形图像处理绪论
- VC图形图像处理大全
- 图形图像处理集锦!
- Jmagick图形图像处理
- Tomcat或Tomcat插件启动不了 [Eclipse中通过Debug模式启动Tomcat,导致Eclipse卡死]终极解决方案
- Just a Hook (线段树)
- 网页优化性能的几个基本注意点
- 计蒜客 数字解码 dp
- Linux下C库学习
- 计算机图形图像处理 实验一
- Canvas的clip方法的使用
- mysql存储过程和函数
- CNN求学之旅[0]
- 京东2017实习生招聘试题 下列关于抽象类说法错误的是
- kmp字符串匹配模板(c++)
- Android:Service的常驻
- 算法第四版练习题答案
- Windows下php执行exec函数调用python