计算机图形图像处理 实验一

计算机图形图像实验

  • 计算机图形图像实验
    • 一 图像处理初步
      • opencv安装配置
      • 图像读取与显示
      • 图像信息
    • 二 图像基本运算
      • 加减乘除
        • 图形相加
        • 图形相减
        • 图像相乘
        • 图像相除
      • 图像灰度级变换
        • 图像求反
      • 图像变换
        • 图像平移
        • 图像缩放
        • 图像旋转
      • 直方图均衡化处理

一. 图像处理初步

1. opencv安装,配置

VS配置opencv时,要修改三个地方,如下图

计算机图形图像处理 实验一_第1张图片

计算机图形图像处理 实验一_第2张图片

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("图片相加");
}

实验结果:

计算机图形图像处理 实验一_第3张图片 计算机图形图像处理 实验一_第4张图片 计算机图形图像处理 实验一_第5张图片
图像一 图像二 结果

图形相减

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("图片相减");

}
计算机图形图像处理 实验一_第6张图片 计算机图形图像处理 实验一_第7张图片 计算机图形图像处理 实验一_第8张图片
图片一 图片二 结果

图像相乘

这里用的是二值蒙板图像与原图像相乘,为了实现一定的效果(去除背景),这里并没有直接使用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("图片相乘");
}
计算机图形图像处理 实验一_第9张图片 计算机图形图像处理 实验一_第10张图片 计算机图形图像处理 实验一_第11张图片
图片一 图片二 结果

图像相除

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("图片相除");
}
计算机图形图像处理 实验一_第12张图片 计算机图形图像处理 实验一_第13张图片 计算机图形图像处理 实验一_第14张图片
图片一 图片二 结果

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("图片求反");

}
计算机图形图像处理 实验一_第15张图片 计算机图形图像处理 实验一_第16张图片
图片一 结果

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("图片平移");

}
计算机图形图像处理 实验一_第17张图片 计算机图形图像处理 实验一_第18张图片
图片一 结果

图像缩放

这里输入图像宽和高的缩放倍数(> 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("图片缩放");

}
计算机图形图像处理 实验一_第19张图片 计算机图形图像处理 实验一_第20张图片
图片1 结果

图像旋转

图像旋转后,会导致图像显示不全,这里图像旋转后,大小会发生变化,使图片能够显示完全

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("图片旋转");

}
计算机图形图像处理 实验一_第21张图片 计算机图形图像处理 实验一_第22张图片
图片1 结果

4.直方图均衡化处理

要求:自己编写函数,不能使用opencv自带函数(虽然我也不知道自带函数是什么…)

直方图均衡化是将原图像通过某种变换,得到一幅图像,整个图像灰度直方图为均匀分布的新图像的方法。

根据个人理解,直方图均衡化处理大致有如下步骤:

  1. 灰度直方图统计hist[0..L-1]: 图像有L灰度级(L=256,即8位灰度级),统计各个灰度级在图像中出现的次数,之后hist[]/=图像像素。
  2. 归一化累积直方图t[0..L-1]: 计算方式为t[x] = t[x-1] + s[x]
  3. 遍历图像,根据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("直方图均衡化");
}
计算机图形图像处理 实验一_第23张图片 计算机图形图像处理 实验一_第24张图片
原图片 增强后图片

你可能感兴趣的:(计算机图形图像处理)