数字图像处理第二次作业

摘要:本次实验通过运用OpenCV进行编程,主要完成了1.把附件图像的直方图画出;2.把所有图像进行直方图均衡;输出均衡后的图像和源图像进行比对;发现了均衡后图像的对比度加大等特点;3.进一步把图像按照对源图像直方图的观察,各自指定不同源图像的直方图,进行直方图匹配,进行图像增强;4.利用直方图对图像elain和woman进行分割;的任务。

原图像

 

         Citywall                    Citywall1 

      Citywall2                      Elain 

            Elain1                      Elain2 

        Elain3                      lena 

            Lena1                      Lena2 

           Lena4                       Woman 

            Woman1                Woman2

1. 把附件图像的直方图画出

1.1. 分析

首先使用cvCalcHist();函数将计算出图像的直方图中的数据,即每个灰度各有多少个像素点,存在hist中。然后使用cvGetMinMaxHistValue()函数获取直方图中的极大值用于归一化显示。然后通过获取cvQueryHistValue_1D()函数获取具体每个灰度的值,然后如下图所示通过获取四边形的四个坐标点,然后填充白色,最终获得了直方图。

1.2. 程序核心代码

//绘制直方图,出自庞老师的教程:www.opencvchina.com,想详细了解的童鞋可以去那看看

IplImage* DrawHistogram(CvHistogram* hist , float scaleX = 1 , float scaleY = 1)

{

 

        //获取直方图中极大值

        float histMax = 0;

        cvGetMinMaxHistValue(hist , 0 ,&histMax ,0 ,0);

 

        //创建图像 该图像用于显示直方图

        IplImage* imgHist = cvCreateImage(cvSize(256*scaleX , 64*scaleY) , 8 ,1);

 

        //图像置零

        cvZero(imgHist);

 

        //依次绘制直方图的bin

        for(int i=0;i<255;i++)

        {

 

                //获取直方图的值

                float histValue = cvQueryHistValue_1D(hist , i);

                float nextValue = cvQueryHistValue_1D(hist , i+1);

 

 

 

                //获取四边形的四个点的坐标 减是为了向上生长

                CvPoint pt1 = cvPoint(      i*scaleX , 64*scaleY);

                CvPoint pt2 = cvPoint(  (i+1)*scaleX , 64*scaleY);

                CvPoint pt3 = cvPoint(  (i+1)*scaleX , (64 - (nextValue/histMax)*64) *scaleY );

                CvPoint pt4 = cvPoint (      i*scaleX , (64 - (histValue/histMax)*64) *scaleY );

 

                int numPts = 5;

                CvPoint pts[5];

                pts[0] = pt1;

                pts[1] = pt2;

                pts[2] = pt3;

                pts[3] = pt4;

                pts[4] = pt1;

 

                //填充四边形

                cvFillConvexPoly(imgHist , pts ,numPts , cvScalar(255));

 

        }

 

 

        return imgHist;

 

}

1.3. 结果

楼主较懒,就直接用QQ截图了,要不然一张一张图片向上传太麻烦,童鞋们想要原图的,请向后翻,自己跑代码吧。。。

 

1.4. 小结

由于为了较好的画出直方图,我采用了归一化的方法,所以并不能直接比较出这些直方图上每个灰度有多少像素点这样的数值的绝对大小,只能从灰度的分布来大致分析。

Citywall:

对原图像和citywall1分析知:citywall1将原图像中的灰度值较大的部分(即较亮的部分)给去掉了,图像的像素点大都集中于灰度值较低的部分(较暗的部分),所以citywall1图像整体较暗,但是在灰度值较大的地方仍有像素点分布。

对原图像和citywall2分析知:citywall2将原图像的灰度分布给“压缩”了,使图像的灰度分布的方差减小,使得图像看起来朦胧了很多。

Elain:

对原图像和elain1分析知:同citywall1.

对原图像和elain2、elain3分析知:同citywall2.但是从elain2 和 elain3 的直方图上,我们可以很明显的看出3要比2“压缩” 的更厉害一些,图像显得更加模糊,亮度分布更加均匀一些,同时由于“压缩”在灰度值较低的地方,使得3要比2暗了很多。

Lena:

对原图像和lena1分析知:同citywall1但是lena由于在灰度较高的地方仍有大量的像素点分布,所以部分较亮。

对原图像和lena2分析知:同citywall2. 但是lena2图像像素灰度集中在灰度较高的地方,图像较亮。

对原图像和lena4和lena1分析知:图像4减少了灰度较大的像素点的分布,图像会较暗。

Woman:

对原图像和woman1分析知:同citywall1.

对原图像和woman2、woman1分析知:相较于woman1,woman2的灰度较大的地区分布较多,亮度较高。

2. 把所有图像进行直方图均衡;输出均衡后的图像和源图像进行比对;分析改善内容

2.1. 分析

使用cvEqualizeHist();函数进行直方图均衡。

2.2. 程序核心代码

以citywall1为例

cvEqualizeHist(citywall1,citywall1);

2.3. 结果

好吧,全部上传太麻烦了,下面就举几个例子吧

citywall

citywall1

citywall2

。。。。。。

2.4. 小结

分析上面的图片,我们可以很容易的看出经过均衡化处理后,图像的对比度加大了。

3. 进一步把图像按照对源图像直方图的观察,各自指定不同源图像的直方图,进行直方图匹配,进行图像增强;

3.1. 分析

直方图匹配:是指使一幅图像的直方图变成规定形状的直方图而进行的图像增强方法。将图像直方图以标准图像的直方图为标准作变换,使两图像的直方图相同和近似, 从而使两幅图像具有类似的色调和反差。通过使用cvCalcHist(),cvNormalizeHist() 等函数,将所得的结果存放在数组当中,通过计算其差值判断图像的灰度值的应当加大还是减小,从而实现了直方图的匹配。

 

3.2. 核心源代码

void myHistMatch(IplImage *img,IplImage* img_m) 

{ 

    int bins = 256; 

    int sizes[] = {bins};

 

    CvHistogram *hist = cvCreateHist(1,sizes,CV_HIST_ARRAY);

    CvHistogram *hist_m = cvCreateHist(1,sizes,CV_HIST_ARRAY);

 

    cvCalcHist(&img,hist); 

    cvCalcHist(&img_m,hist_m); 

 

    cvNormalizeHist(hist,1); 

    cvNormalizeHist(hist_m,1); 

 

    double val_1 = 0.0; 

    double val_2 = 0.0; 

    uchar T[256] = {0}; 

    double S[256] = {0}; 

    double G[256] = {0}; 

    for (int index = 0; index<256; ++index) 

    { 

        val_1 += cvQueryHistValue_1D(hist,index); 

        val_2 += cvQueryHistValue_1D(hist_m,index); 

        G[index] = val_2; 

        S[index] = val_1; 

    } 

 

    double min_val = 0.0; 

    int PG = 0; 

    for ( int i = 0; i<256; ++i) 

    { 

        min_val = 1.0; 

        for(int j = 0;j<256; ++j) 

        { 

            if( (G[j] - S[i]) < min_val && (G[j] - S[i]) >= 0) 

            { 

                min_val = (G[j] - S[i]); 

                PG = j; 

            } 

 

        } 

        T[i] = (uchar)PG; 

    } 

 

    uchar *p = NULL; 

    for (int x = 0; x<img->height;++x) 

    {  

        p = (uchar*)(img->imageData + img->widthStep*x); 

        for (int y = 0; y<img->width;++y) 

        { 

            p[y] = T[p[y]]; 

        } 

    } 

}

 

3.3. 结果

 

Citywall

 

Citywall 1

 

Citywall 2

3.4. 小结

通过分析以上图片,我们发现经过直方图匹配后,图像的对比度有所提升,但是有很多地方的细节模糊,看不清,而且有些地方过分增强,严重干扰清晰度。

4. 利用直方图对图像elain和woman进行分割;

4.1. 分析

本次图像分割主要通过图像的每个像素的点的灰度值的大小来进行,通过设置上下界的阈值,使得灰度值不在范围内的像素点置零,从而实现了背景和人物之间的分离。

 

注:实际写代码时,为了使的滚动条的改变可以时时反应在图像上,在主程序中加了一个while循环

4.2. 核心源代码

//高于上限或低于下限置0

void HistThreshold(IplImage* img, int m_lowerLimit, int m_upperLimit)

{      

    int imgDepth = img->depth;          

    int imgChannels = img->nChannels;                    

    int imgStep = img->widthStep/sizeof(uchar);

    uchar* imgData  = (uchar *)img->imageData; 

 

    for(int i = 0 ;i < img->height; i++)

    {

        for(int j =0 ; j <img->width ; j++)

        {

            for(int k = 0; k<imgChannels;k++)

            {

                //当灰度值不在范围之内时灰度值付为0,否则为255

                if( imgData[i*imgStep+j*imgChannels+k] <m_lowerLimit || imgData[i*imgStep+j*imgChannels+k] > m_upperLimit)

                (((uchar *)(img->imageData))[i*imgStep+j*imgChannels+k]) = 0;      

            }

        }  

    }

 

}

 

4.3. 结果

 

Elain

 

Woman

4.4. 小结

通过分析上面两幅图像,我们知道将elain 的灰度值范围设置为(162, 240)较为理想,而对woman,其灰度值范围设置为(160, 252)则较优。而且woman的背景图像灰度值较为单一,elain背景图像灰度值则分布范围较大,使得woman 的分割明显好于elain的分割。而从总体上看,灰度值设置阈值分割会使要分割的部分产生部分失真,而且收环境影响较大,不是一种理想的分割方式。

5. 总结

通过本次实验,又再次熟悉了OpenCV的使用,实验过程中也和上次实验一样遇到了很多的bug,但是好在今天的网络资源的丰富,以及一些好心的博客园主的耐心回答,才能完成本次作业。

6. 源代码

6.1. 第一题

 

// Homework No2.cpp : Defines the entry point for the console application.
// houqiqi

#include "stdafx.h"
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <cv.h>


using namespace std;
using namespace cv;

//绘制直方图
IplImage* DrawHistogram(CvHistogram* hist , float scaleX = 1 , float scaleY = 1)
{

        //获取直方图中极大值
        float histMax = 0;
        cvGetMinMaxHistValue(hist , 0 ,&histMax ,0 ,0);

        //创建图像 该图像用于显示直方图
        IplImage* imgHist = cvCreateImage(cvSize(256*scaleX , 64*scaleY) , 8 ,1);

        //图像置零
        cvZero(imgHist);

        //依次绘制直方图的bin
        for(int i=0;i<255;i++)
        {

                //获取直方图的值
                float histValue = cvQueryHistValue_1D(hist , i);
                float nextValue = cvQueryHistValue_1D(hist , i+1);



                //获取四边形的四个点的坐标 
                CvPoint pt1 = cvPoint(      i*scaleX , 64*scaleY);
                CvPoint pt2 = cvPoint(  (i+1)*scaleX , 64*scaleY);
                CvPoint pt3 = cvPoint(  (i+1)*scaleX , (64 - (nextValue/histMax)*64) *scaleY );
                CvPoint pt4 = cvPoint (      i*scaleX , (64 - (histValue/histMax)*64) *scaleY );

                int numPts = 5;
                CvPoint pts[5];
                pts[0] = pt1;
                pts[1] = pt2;
                pts[2] = pt3;
                pts[3] = pt4;
                pts[4] = pt1;

                //填充四边形
                cvFillConvexPoly(imgHist , pts ,numPts , cvScalar(255));

        }


        return imgHist;

}


int _tmain(int argc, _TCHAR* argv[])
{
    //load images
    IplImage* citywall    = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\citywall.bmp",0);
    IplImage* citywall1 = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\citywall1.bmp",0);
    IplImage* citywall2 = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\citywall2.bmp",0);
    IplImage* elain        = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\elain.bmp",0);
    IplImage* elain1    = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\elain1.bmp",0);
    IplImage* elain2    = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\elain2.bmp",0);
    IplImage* elain3    = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\elain3.bmp",0);
    IplImage* lena        = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\lena.bmp",0);
    IplImage* lena1        = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\lena1.bmp",0);
    IplImage* lena2        = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\lena2.bmp",0);
    IplImage* lena4        = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\lena4.bmp",0);
    IplImage* woman        = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\woman.bmp",0);
    IplImage* woman1    = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\woman1.bmp",0);
    IplImage* woman2    = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\woman2.bmp",0);

    int dims = 1;  // 一维直方图
    int size =256; //bin的个数
    float range[] = {0,255}; //取值范围
    float* ranges[] = {range};

     CvHistogram* hist;

     //创建直方图
     hist = cvCreateHist(dims , &size , CV_HIST_ARRAY ,  ranges , 1 );

    //清空直方图
    cvClearHist(hist);

    //计算citywall的直方图
    cvCalcHist(&citywall , hist , 0 , 0 );

    //绘制citywall直方图  结果保存在histCitywall
    IplImage* hist_citywall = DrawHistogram(hist);

    //将B通道的直方图数据清空
    cvClearHist(hist);

    //下面类似
    //对citywall1
    cvCalcHist(&citywall1 , hist , 0 , 0 );
    IplImage* hist_citywall1 = DrawHistogram(hist);
    cvClearHist(hist);

    //citywall2
    cvCalcHist(&citywall2 , hist , 0 , 0 );
    IplImage* hist_citywall2 = DrawHistogram(hist);
    cvClearHist(hist);

    //elain
    cvCalcHist(&elain , hist , 0 , 0 );
    IplImage* hist_elain = DrawHistogram(hist);
    cvClearHist(hist);

    //elain1
    cvCalcHist(&elain1 , hist , 0 , 0 );
    IplImage* hist_elain1 = DrawHistogram(hist);
    cvClearHist(hist);

    //elain2
    cvCalcHist(&elain2 , hist , 0 , 0 );
    IplImage* hist_elain2 = DrawHistogram(hist);
    cvClearHist(hist);

    //elain3
    cvCalcHist(&elain3 , hist , 0 , 0 );
    IplImage* hist_elain3 = DrawHistogram(hist);
    cvClearHist(hist);

    //lena
    cvCalcHist(&lena , hist , 0 , 0 );
    IplImage* hist_lena = DrawHistogram(hist);
    cvClearHist(hist);
    
    //lena1
    cvCalcHist(&lena1 , hist , 0 , 0 );
    IplImage* hist_lena1 = DrawHistogram(hist);
    cvClearHist(hist);
    
    //lena2
    cvCalcHist(&lena2 , hist , 0 , 0 );
    IplImage* hist_lena2 = DrawHistogram(hist);
    cvClearHist(hist);
    
    //lena4
    cvCalcHist(&lena4 , hist , 0 , 0 );
    IplImage* hist_lena4 = DrawHistogram(hist);
    cvClearHist(hist);

    //woman
    cvCalcHist(&woman , hist , 0 , 0 );
    IplImage* hist_woman = DrawHistogram(hist);
    cvClearHist(hist);
    
    //woman1
    cvCalcHist(&woman1 , hist , 0 , 0 );
    IplImage* hist_woman1 = DrawHistogram(hist);
    cvClearHist(hist);
    
    //woman2
    cvCalcHist(&woman2 , hist , 0 , 0 );
    IplImage* hist_woman2 = DrawHistogram(hist);
    cvClearHist(hist);

    cvNamedWindow ("hist_citywall",CV_WINDOW_AUTOSIZE);
    cvNamedWindow ("hist_citywall1",CV_WINDOW_AUTOSIZE);
    cvNamedWindow ("hist_citywall2",CV_WINDOW_AUTOSIZE);
    cvNamedWindow ("hist_elain",CV_WINDOW_AUTOSIZE);
    cvNamedWindow ("hist_elain1",CV_WINDOW_AUTOSIZE);
    cvNamedWindow ("hist_elain2",CV_WINDOW_AUTOSIZE);
    cvNamedWindow ("hist_elain3",CV_WINDOW_AUTOSIZE);
    cvNamedWindow ("hist_lena",CV_WINDOW_AUTOSIZE);
    cvNamedWindow ("hist_lena1",CV_WINDOW_AUTOSIZE);
    cvNamedWindow ("hist_lena2",CV_WINDOW_AUTOSIZE);
    cvNamedWindow ("hist_lena4",CV_WINDOW_AUTOSIZE);
    cvNamedWindow ("hist_woman",CV_WINDOW_AUTOSIZE);
    cvNamedWindow ("hist_woman1",CV_WINDOW_AUTOSIZE);
    cvNamedWindow ("hist_woman2",CV_WINDOW_AUTOSIZE);

    cvShowImage("hist_citywall",hist_citywall);
    cvShowImage("hist_citywall1",hist_citywall1);
    cvShowImage("hist_citywall2",hist_citywall2);
    cvShowImage("hist_elain",hist_elain);
    cvShowImage("hist_elain1",hist_elain1);
    cvShowImage("hist_elain2",hist_elain2);
    cvShowImage("hist_elain3",hist_elain3);
    cvShowImage("hist_lena",hist_lena);
    cvShowImage("hist_lena1",hist_lena1);
    cvShowImage("hist_lena2",hist_lena2);
    cvShowImage("hist_lena4",hist_lena4);
    cvShowImage("hist_woman",hist_woman);
    cvShowImage("hist_woman1",hist_woman1);
    cvShowImage("hist_woman2",hist_woman2);

    cvWaitKey(0);

    return 0;
}

6.2. 第二题

// Homework No2.cpp : Defines the entry point for the console application.
// houqiqi

#include "stdafx.h"
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <cv.h>


using namespace std;
using namespace cv;

int _tmain(int argc, _TCHAR* argv[])
{
    //load images
    IplImage* citywall    = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\citywall.bmp",0);
    IplImage* citywall1 = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\citywall1.bmp",0);
    IplImage* citywall2 = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\citywall2.bmp",0);
    IplImage* elain        = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\elain.bmp",0);
    IplImage* elain1    = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\elain1.bmp",0);
    IplImage* elain2    = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\elain2.bmp",0);
    IplImage* elain3    = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\elain3.bmp",0);
    IplImage* lena        = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\lena.bmp",0);
    IplImage* lena1        = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\lena1.bmp",0);
    IplImage* lena2        = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\lena2.bmp",0);
    IplImage* lena4        = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\lena4.bmp",0);
    IplImage* woman        = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\woman.bmp",0);
    IplImage* woman1    = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\woman1.bmp",0);
    IplImage* woman2    = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\woman2.bmp",0);

    cvEqualizeHist(citywall,citywall);
    cvEqualizeHist(citywall1,citywall1);
    cvEqualizeHist(citywall2,citywall2);
    cvEqualizeHist(elain,elain);
    cvEqualizeHist(elain1,elain1);
    cvEqualizeHist(elain2,elain2);
    cvEqualizeHist(elain3,elain3);
    cvEqualizeHist(lena,lena);
    cvEqualizeHist(lena1,lena1);
    cvEqualizeHist(lena2,lena2);
    cvEqualizeHist(lena4,lena4);
    cvEqualizeHist(woman,woman);
    cvEqualizeHist(woman1,woman1);
    cvEqualizeHist(woman2,woman2);

    cvNamedWindow("citywall",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("citywall1",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("citywall2",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("elain",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("elain1",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("elain2",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("elain3",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("lena",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("lena1",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("lena2",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("lena4",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("woman",0);
    cvNamedWindow("woman1",2);
    cvNamedWindow("woman2",2);

    cvShowImage("citywall",citywall);
    cvShowImage("citywall1",citywall1);
    cvShowImage("citywall2",citywall2);
    cvShowImage("elain",elain);
    cvShowImage("elain1",elain1);
    cvShowImage("elain2",elain2);
    cvShowImage("elain3",elain3);
    cvShowImage("lena",lena);
    cvShowImage("lena1",lena1);
    cvShowImage("lena2",lena2);
    cvShowImage("lena4",lena4);
    cvShowImage("woman",woman);
    cvShowImage("woman1",woman1);
    cvShowImage("woman2",woman2);

    cvWaitKey(0);

    return 0;
}

6.3. 第三题

// Homework No2.cpp : Defines the entry point for the console application.
// houqiqi

#include "stdafx.h"
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <cv.h>


using namespace std;
using namespace cv;

void myHistMatch(IplImage *img,IplImage* img_m)  
{  
    int bins = 256;  
    int sizes[] = {bins}; 

    CvHistogram *hist = cvCreateHist(1,sizes,CV_HIST_ARRAY);
    CvHistogram *hist_m = cvCreateHist(1,sizes,CV_HIST_ARRAY);

    cvCalcHist(&img,hist);  
    cvCalcHist(&img_m,hist_m);  

    cvNormalizeHist(hist,1);  
    cvNormalizeHist(hist_m,1);  

    double val_1 = 0.0;  
    double val_2 = 0.0;  
    uchar T[256] = {0};  
    double S[256] = {0};  
    double G[256] = {0};  
    for (int index = 0; index<256; ++index)  
    {  
        val_1 += cvQueryHistValue_1D(hist,index);  
        val_2 += cvQueryHistValue_1D(hist_m,index);  
        G[index] = val_2;  
        S[index] = val_1;  
    }  
  
    double min_val = 0.0;  
    int PG = 0;  
    for ( int i = 0; i<256; ++i)  
    {  
        min_val = 1.0;  
        for(int j = 0;j<256; ++j)  
        {  
            if( (G[j] - S[i]) < min_val && (G[j] - S[i]) >= 0)  
            {  
                min_val = (G[j] - S[i]);  
                PG = j;  
            }  
  
        }  
        T[i] = (uchar)PG;  
    }  
  
    uchar *p = NULL;  
    for (int x = 0; x<img->height;++x)  
    {   
        p = (uchar*)(img->imageData + img->widthStep*x);  
        for (int y = 0; y<img->width;++y)  
        {  
            p[y] = T[p[y]];  
        }  
    }  
}


int _tmain(int argc, _TCHAR* argv[])
{
    //load images
    IplImage* citywall    = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\citywall.bmp",0);
    IplImage* citywall1 = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\citywall1.bmp",0);
    IplImage* citywall2 = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\citywall2.bmp",0);
    IplImage* elain        = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\elain.bmp",0);
    IplImage* elain1    = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\elain1.bmp",0);
    IplImage* elain2    = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\elain2.bmp",0);
    IplImage* elain3    = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\elain3.bmp",0);
    IplImage* lena        = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\lena.bmp",0);
    IplImage* lena1        = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\lena1.bmp",0);
    IplImage* lena2        = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\lena2.bmp",0);
    IplImage* lena4        = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\lena4.bmp",0);
    IplImage* woman        = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\woman.bmp",0);
    IplImage* woman1    = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\woman1.bmp",0);
    IplImage* woman2    = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\woman2.bmp",0);

    myHistMatch(citywall,citywall);
    myHistMatch(citywall1,citywall);
    myHistMatch(citywall2,citywall);
    myHistMatch(elain,elain);
    myHistMatch(elain1,elain);
    myHistMatch(elain2,elain);
    myHistMatch(elain3,elain);
    myHistMatch(lena,lena);
    myHistMatch(lena1,lena);
    myHistMatch(lena2,lena);
    myHistMatch(lena4,lena);
    myHistMatch(woman,woman);
    myHistMatch(woman1,woman);
    myHistMatch(woman2,woman);

    cvNamedWindow("citywall",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("citywall1",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("citywall2",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("elain",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("elain1",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("elain2",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("elain3",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("lena",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("lena1",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("lena2",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("lena4",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("woman",0);
    cvNamedWindow("woman1",2);
    cvNamedWindow("woman2",2);

    cvShowImage("citywall",citywall);
    cvShowImage("citywall1",citywall1);
    cvShowImage("citywall2",citywall2);
    cvShowImage("elain",elain);
    cvShowImage("elain1",elain1);
    cvShowImage("elain2",elain2);
    cvShowImage("elain3",elain3);
    cvShowImage("lena",lena);
    cvShowImage("lena1",lena1);
    cvShowImage("lena2",lena2);
    cvShowImage("lena4",lena4);
    cvShowImage("woman",woman);
    cvShowImage("woman1",woman1);
    cvShowImage("woman2",woman2);

    cvWaitKey(0);

    return 0;
}

6.4. 第四题

// Homework No2.cpp : Defines the entry point for the console application.
// houqiqi

#include "stdafx.h"
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <cv.h>


using namespace std;
using namespace cv;

//记录滚动条的当前位置
int g_slider_pos_low = 0;
int g_slider_pos_high = 255;

//刚开始时的上下限的值
int m_lowerLimit = 0;
int m_upperLimit = 255;
int w_lowerLimit = 0;
int w_upperLimit = 255;

//滚动条回调函数
void onTrackbarSlider_low(int pos)
{      
    m_lowerLimit = pos ;
}

void onTrackbarSlider_high(int pos)
{      
    m_upperLimit = pos ;
}
void onTrackbarSlider_low_w(int pos) { w_lowerLimit = pos ; } void onTrackbarSlider_high_w(int pos) { w_upperLimit = pos ; } //高于上限或低于下限置0 void HistThreshold(IplImage* img, int m_lowerLimit, int m_upperLimit) { int imgDepth = img->depth; int imgChannels = img->nChannels; int imgStep = img->widthStep/sizeof(uchar); uchar* imgData = (uchar *)img->imageData; for(int i = 0 ;i < img->height; i++) { for(int j =0 ; j <img->width ; j++) { for(int k = 0; k<imgChannels;k++) { //当灰度值不在范围之内时灰度值付为0,否则为255 if( imgData[i*imgStep+j*imgChannels+k] <m_lowerLimit || imgData[i*imgStep+j*imgChannels+k] > m_upperLimit) (((uchar *)(img->imageData))[i*imgStep+j*imgChannels+k]) = 0; } } } } int _tmain(int argc, _TCHAR* argv[]) { //load images IplImage* elain = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\elain.bmp",0); IplImage* woman = cvLoadImage("C:\\Users\\qiqi\\Desktop\\第2次作业\\woman.bmp",0); cvNamedWindow("elain",CV_WINDOW_AUTOSIZE); cvNamedWindow("woman",0); //创建滚动条 cvCreateTrackbar( "m_lowerLimit", "elain", &g_slider_pos_low, 255, onTrackbarSlider_low ); cvCreateTrackbar( "m_upperLimit", "elain", &g_slider_pos_high, 255, onTrackbarSlider_high ); cvCreateTrackbar( "m_lowerLimit", "woman", &g_slider_pos_low, 255, onTrackbarSlider_low_w ); cvCreateTrackbar( "m_upperLimit", "woman", &g_slider_pos_high, 255, onTrackbarSlider_high_w ); //为了使滚动条的改变时时反应到图片上,要有一循环 while(1) { HistThreshold(elain, m_lowerLimit, m_upperLimit); HistThreshold(woman, w_lowerLimit, w_upperLimit); cvShowImage("elain",elain); cvShowImage("woman",woman); cvWaitKey(27); } //貌似原来的代码都忘了释放内存和销毁窗口了 cvDestroyAllWindows(); cvReleaseImage(&elain); cvReleaseImage(&woman); return 0; }

7. 参考资料

小魏的博客:http://blog.csdn.net/xiaowei_cqu/article/details/7600666

庞峰老师的视频:www.opencvchina.com

原文地址:https://www.cnblogs.com/hqqxyy/p/2962433.html