彩色图像的直方图绘制及灰度图像均衡化
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;
像素值读写的几种方法:
-
方法一:
-
单通道读像素
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; } }
-
彩色图像(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; } }
-
-
方法二:
-
单通道读像素
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; }
-
彩色图像(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 }
-
-
方法三:
-
单通道
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