#define U8_GRAY_LEVEL 256
// 显示直方图
/*
pImgData:图像指针
nImgW:图像宽
nImgH:图像高
nIdHist:显示控件ID(picture control)
*/
INT32 CImageWindowDlg::ShowArrHist(UINT8 *pImgData, int nImgW, int nImgH, int nIdHist)
{
// 计算直方图
int pnHist[U8_GRAY_LEVEL] = { 0 };
getEqualHist(pImgData, nImgW*nImgH, pnHist);
int pArrTemp[U8_GRAY_LEVEL] = { 0 };
memcpy(pArrTemp, pnHist, U8_GRAY_LEVEL * sizeof(int));
int nTemp = 0; // 冒泡法 从高到低排序
for (int i = 0; i < U8_GRAY_LEVEL; ++i)
{
for (int j = U8_GRAY_LEVEL - 1; j > i; --j)
{
if (pArrTemp[j] > pArrTemp[j - 1])
{
nTemp = pArrTemp[j];
pArrTemp[j] = pArrTemp[j - 1];
pArrTemp[j - 1] = nTemp;
}
}
}
// 选择参考值,一般最大值太大,先从第三个数为参考点
int nRef = 1;
if (pArrTemp[2] != 0)
{
nRef = pArrTemp[2];
}
else if (pArrTemp[1] != 0)
{
nRef = pArrTemp[1];
}
else if (pArrTemp[0] != 0)
{
nRef = pArrTemp[0];
}
else
{
return FALSE;
}
// 绘制的笔
CPen *pPen = new CPen();
pPen->CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
CPen *pPen2 = new CPen();
pPen2->CreatePen(PS_SOLID, 1, RGB(60, 60, 255));
CRect rectHist, rect;
CString str_Temp;
GetDlgItem(nIdHist)->GetWindowRect(rectHist);
ScreenToClient(&rectHist);
int nLeftMargin = 2; // 左边空白
int nRightMargin = nLeftMargin; // 右边空白
int nTopMargin = 5; // 上部空白
int nButtomMargin = 20; // 底部空隙,用于显示刻度
GetDlgItem(nIdHist)->MoveWindow(rectHist.left, rectHist.top, rectHist.Width(), rectHist.Height(), TRUE);
//rectHist.InflateRect(0, 0, nLeftMargin + nRightMargin + 255 - rectHist.Width(), 0); // 增加宽和高
CWnd *pWnd = GetDlgItem(nIdHist);
pWnd->GetClientRect(&rect);
CDC *pDCHist = pWnd->GetDC();
CGdiObject *pPenOld = pDCHist->SelectObject(pPen);
int i = 0; // 循环变量
int nW = rectHist.Width();
int nH = rectHist.Height();
int nYmaxPx = nLeftMargin; // Y坐标轴最大值的位置的横坐标
int nYmaxPy = nTopMargin;
int nXmaxPx = rectHist.Width() - nRightMargin;
int nXmaxPy = rectHist.Height() - nButtomMargin;
int pnXPx[10] = { 0 }; // X轴刻度位置
int pnXPx10[30] = { 0 }; // X轴刻度位置,10一个刻度
int pnYPx[10] = { 0 }; // Y轴刻度位置
int nSacle = 256 / 50 + 1; // 多少个刻度
int nSacle10 = 256 / 10 + 1; // 多少个小刻度
int nSacleY = 4;
for (i = 0; i < nSacle; ++i)
{
pnXPx[i] = nLeftMargin + (rectHist.Width() - nRightMargin - nLeftMargin) * i * 50 / 255; // X轴刻度位置
}
pnXPx[i] = rectHist.Width() - nRightMargin;
for (i = 0; i < nSacle10; ++i)
{
pnXPx10[i] = nLeftMargin + (rectHist.Width() - nRightMargin - nLeftMargin) * i * 10 / 255; // X轴刻度位置
}
pnXPx10[i] = rectHist.Width() - nRightMargin;
for (i = 0; i <= nSacleY; ++i)
{
pnYPx[i] = nTopMargin + (rectHist.Height() - nButtomMargin - nTopMargin) * i / nSacleY; // Y轴刻度位置
}
pDCHist->Rectangle(0, 0, rectHist.Width() + 1, rectHist.Height()); //画一个矩形框
pDCHist->MoveTo(nLeftMargin, rectHist.Height() - nButtomMargin);
pDCHist->LineTo(rectHist.Width() - nRightMargin, rectHist.Height() - nButtomMargin);
for (i = 1; i < nSacle - 1; i++)
{
str_Temp.Format(_T("%d"), i * 50);
pDCHist->TextOut(pnXPx[i] - 12, nXmaxPy + 2, str_Temp);
}
pDCHist->TextOut(pnXPx[0] + 1, nXmaxPy + 2, _T("0"));
pDCHist->TextOut(pnXPx[i] - 20, nXmaxPy + 2, _T("250"));
for (i = 1; i <= nSacle; i++)
{
pDCHist->MoveTo(pnXPx[i], nXmaxPy + 3); //绘制X轴刻度
pDCHist->LineTo(pnXPx[i], nXmaxPy - 3);
}
for (i = 1; i <= nSacle10; i++)
{
pDCHist->MoveTo(pnXPx10[i], nXmaxPy + 1); //绘制X轴的小刻度
pDCHist->LineTo(pnXPx10[i], nXmaxPy - 2);
}
// 绘制Y轴
pDCHist->MoveTo(nLeftMargin, nTopMargin);
pDCHist->LineTo(nLeftMargin, rectHist.Height() - nButtomMargin);
for (i = 0; i < nSacleY; i++)
{
pDCHist->MoveTo(nYmaxPx, pnYPx[i]); //写Y轴刻度线
pDCHist->LineTo(nYmaxPx + 3, pnYPx[i]);
}
str_Temp.Format(_T("%d"), nRef);
pDCHist->TextOut(pnYPx[0] + 1, nTopMargin - 4, str_Temp);
// 显示直方图
pDCHist->SelectObject(pPen2);
for (i = 0; i < U8_GRAY_LEVEL; i++)
{
int nPx = nLeftMargin + (rectHist.Width() - nRightMargin - nLeftMargin) * (i) / 255;
int nPy1 = rectHist.Height() - nButtomMargin;
int nPy2 = nPy1 - (nPy1 - nTopMargin) * pnHist[i] / nRef;
nPy2 = nPy2 > nTopMargin ? nPy2 : nTopMargin; // 防止溢出
//nPy2 = nPy2 > nTopMargin ? nPy2 : 0; // 防止溢出
pDCHist->MoveTo(nPx, nPy1);
pDCHist->LineTo(nPx, nPy2);
}
pDCHist->SelectObject(pPenOld);
delete pPen;
delete pPen2;
ReleaseDC(pDCHist);
return TRUE;
}
MFC画图像直方图
最新推荐文章于 2024-02-10 23:44:42 发布