彩色图像的直方图绘制及灰度图像均衡化

Mat容器

  Mat E = Mat :: eye(4,4,CV_64F);
  cout << “E =” << endl << “” << E << endl << endl;
  Mat O = Mat :: ones(2,2,CV_32F);
  cout << “O =” << endl << “” <<“O << endl << endl;
  Mat Z = Mat :: zeros(3,3,CV_8UC1);
  cout << “Z =” << endl << “” << Z << endl << endl;

像素值读写的几种方法:

  • 方法一:

    1. 单通道读像素uchar value = grayimg.at<uchar>(i,j);

      for(int i=0;i<grayimg.rows;i++)
      {
        for(int j=0;j<grayimg.cols;j++)
        {
          grayimg.at<uchar>(i,j)=(i+j)%255;
        }
      }
    2. 彩色图像(BGR)-3通道

      for(int i=0;i<colorimg.rows;i++)
      {
        for(int j=0;j<colorimg.cols;j++) {
          Vec3b pixel;
          pixel[0]=i%255;//Blue
          pixel[1]=j%/255;//Green
          pixel[2]=0;//Red
          colorimg.at<Vec3b>(i,j)=pixel;
        }
      }
  • 方法二:

    1. 单通道读像素cv::Mat Iterator_<uchar>grayit,grayend;

      cv::Mat Iterator_<uchar> grayit,grayend;
      for(grayit = grayimg.begin<uchar>(),
      grayend = grayimg.end<uchar>();
      grayit != grayend;
      grayit++)
      {
          *grayit=rand()%255;
      }
    2. 彩色图像(BGR)-3通道

      MatIterator_<Vec3b> colorit,colorend;
      for(colorit=colorimg.begin<Vec3b>(),
      colorend=colorimg.end<Vec3>();
      colorit != colorend;
      colorit++) {
        (*colorit)[0]=rand()%255;//Blue
        (*colorit)[1]=rand()%255;//Green
        (*colorit)[2]=rand()%255;//Red
      }
  • 方法三:

    1. 单通道

      for(int i=0;i<grayimg.rows;i++)
      {
        //获取第i行首像素指针
        uchar *p=grayimg.ptr<uchar>(i);
        for(int j=0;j<grayimg.cols;j++)
        {
          //对第i行每个像素(byte)操作
          p[j] = (i+j)%255;
        }
      }

彩色图像的直方图实现

//绘制彩色图像的直方图
void colorGraph()
{
    string src = "../img/tiger.jpg";
    Mat img = imread(src,IMREAD_COLOR);
    namedWindow("colorimg",WINDOW_AUTOSIZE);
    imshow("colorimg",img);
    Mat colorimg = Mat::zeros(600, 800, CV_8UC3);

    //存放3个通道的各个灰度级像素数
    vector<int> num0(256);
    vector<int> num1(256);
    vector<int> num2(256);

    //遍历图形像素,
    for (int i = 0; i < img.rows; i++)
    {
        for (int j = 0; j < img.cols; j++)
        {
            Vec3b pix;
            pix = img.at<Vec3b>(i,j);
            //递增每个灰度级的像素数
            num0[(int)pix[0]]++;
            num1[pix[1]]++;
            num2[pix[2]]++;

        }
    }
    //绘制直方图
    //x,y,o的坐标终点
    Point o = Point(0,800);
    Point x = Point(500,700);
    Point y = Point(0,0);

    line(colorimg, o, y, Scalar(255, 0, 0));
    line(colorimg, o, x, Scalar(255, 0, 0));

    auto max0 = max_element(num0.begin(), num0.end());
    auto max1 = max_element(num1.begin(), num1.end());
    auto max2 = max_element(num2.begin(), num2.end());

    int max = *max0 > *max1 ? *max0:*max1;
    max = max > *max2 ? max : *max2;
    cout << max<<endl;

    Point p[3][256];
  //生成坐标点,并绘制
    for (int i = 0; i < 3; i++)
    {
            if (i == 0)
            {
                for (int j = 0; j < 256; j++)
                {
                    p[i][j].x = j*3;
                    p[i][j].y = 800 - int(num0[j] * (700.0 / max));
                }
                for (int j = 1; j < 256; j++)
                {
                    line(colorimg, p[i][j - 1], p[i][j], Scalar(255, 0, 0));
                }
            }
            else if (i == 1)
            {
                for (int j = 0; j < 256; j++)
                {
                    p[i][j].x = j * 3;
                    p[i][j].y = 800 - int(num1[j] * (700.0 / max));
                }
                for (int j = 1; j < 256; j++)
                {
                    line(colorimg, p[i][j - 1], p[i][j], Scalar(0, 255, 0));
                }
            }
            else if(i==2)
            {
                for (int j = 0; j < 256; j++)
                {
                    p[i][j].x = j * 3;
                    p[i][j].y = 800 - int(num2[j] * (700.0 / max));
                }
                for (int j = 1; j < 256; j++)
                {
                    line(colorimg, p[i][j - 1], p[i][j], Scalar(0, 0, 255));
                }
            }
    }

    namedWindow("color直方图", WINDOW_AUTOSIZE);
    imshow("color直方图", colorimg);

}

灰色图形直方图均衡化

/*均衡化*/
void mEqual()
{
    string src = "../img/tiger.jpg";
    Mat img = imread(src, IMREAD_GRAYSCALE);
    namedWindow("oequal", WINDOW_NORMAL);
    cvResizeWindow("oequal", 480, 319);
    imshow("oequal", img);
    Mat afimg = img.clone();
    //计算图像每个灰度级的像素数
    vector<int> n(256);
    //cout << img << endl;
    for (int i = 0; i < img.rows; i++)
    {
        //uchar* p = img.ptr<uchar>(i);
        for (int j = 0; j < img.cols; j++)
        {
            int index = img.at<uchar>(i, j);
            n[index]++;
        }
    }
    vector<double> pr(256);
    int pix_total = img.rows*img.cols;//图形像素总数
    //归一化后,计算概率
    for (int i = 0; i < 256; i++)
    {
        pr[i] = (float)n[i] / pix_total;
    }
    //计算skT
    vector<double> skt(256);
    for (int i = 0; i < 256; i++)
    {
        if (i == 0)
        {
            skt[i] = pr[i];
        }
        else
        {
            skt[i] = skt[i-1]+pr[i];
        }
    }
    //计算sk
    vector<int> sk(256);
    for (int i = 0; i < 256; i++)
    {
        sk[i] = int(255*skt[i]+0.5);
    }

    vector < double > ps(256);
    //计算ps
    for (int i = 0; i < 256; i++)
    {
        ps[sk[i]] += pr[i];
    }

    //计算均衡化后每一灰度级的像素数
    vector<int> res(256);
    for (int i = 0; i < 256; i++)
    {
        res[i] = (int)(ps[i] * pix_total);
        cout << res[i] << endl;
    }
    //绘制
    Mat hist = Mat::zeros(600, 800, CV_8UC3);
    auto Max = max_element(res.begin(),res.end());
    //绘制坐标系
    Point o = Point(0, 800);
    Point x = Point(500, 700);
    Point y = Point(0, 0);

    //x轴
    line(hist, o, x, Scalar(255, 255, 255));
    //y轴
    line(hist, o, y, Scalar(255, 255, 255));

    Point pts[256];//灰度点
    //生成坐标点
    for (int i = 0; i < 256; i++)
    {
        pts[i].x = i * 3;
        pts[i].y = 800-int(res[i] * (700.0 / *Max));
        //cout << pts[i].x << "," << pts[i].y << "," << ps[i] << endl;
    }
    //绘制线
    for (int i = 0; i < 256; i++)
    {
        line(hist, Point(3*i,800), pts[i], Scalar(0, 0, 205));
    }
    //均衡化后图
    for (int i = 0; i < img.rows; i++)
    {
        for (int j = 0; j < img.cols; j++)
        {
            afimg.at<uchar>(i,j)=sk[img.at<uchar>(i,j)];
        }
    }
    namedWindow("equal图", WINDOW_AUTOSIZE);
    imshow("equal图", afimg);

    namedWindow("equal直方图", WINDOW_AUTOSIZE);
    imshow("equal直方图", hist);

}

编辑日期 2019.5.16


猜你喜欢

转载自www.cnblogs.com/qujialin/p/10877287.html