学习数字图像处理的时候写的一些小功能
加载图像后像素点B/G/R的访问:
m_Image.m_pBits[0][y][x]=0;//B
m_Image.m_pBits[1][y][x]=0;//G
m_Image.m_pBits[2][y][x]=0;//R
图像的左上角为源点,向右为X正向,向下为y正向
1:显示RGB分量
void CImage_ProcessingView::OnRgb()
{
// TODO: 在此添加命令处理程序代码
if(m_Image.IsNull()) return;//判断图像是否为空,如果对空图像进行操作会出现未知的错误
int w=m_Image.GetWidth();//获得图像的宽度
int h=m_Image.GetHeight();//获得图像的高度
Cchoose mychoose=new Cchoose();
CStringArray strArray;
strArray.Add(L"R");
strArray.Add(L"G");
strArray.Add(L"B");
mychoose.strArray.Copy(strArray);
mychoose.DoModal();
//this->MessageBox(mychoose.chooseResult);
CString choose = mychoose.chooseResult;
//this->MessageBox(choose);
CString mR=_T("R");
if(choose.Compare(L"R")==0)
{
for (int j=0;j<h;j++)
{
for (int k=0;k<w;k++)
{
m_Image.m_pBits[0][j][k]=m_Image.m_pBits[1][j][k]=m_Image.m_pBits[2][j][k];
}
}
}
else if(choose.Compare(L"G")==0)
{
for (int j=0;j<h;j++)
{
for (int k=0;k<w;k++)
{
m_Image.m_pBits[0][j][k]=m_Image.m_pBits[2][j][k]=m_Image.m_pBits[1][j][k];
}
}
}
else if(choose.Compare(L"B")==0)
{
for (int j=0;j<h;j++)
{
for (int k=0;k<w;k++)
{
m_Image.m_pBits[1][j][k]=m_Image.m_pBits[2][j][k]=m_Image.m_pBits[0][j][k];
}
}
}
Invalidate(1); //强制调用ONDRAW函数,ONDRAW会绘制图像
}
2:显示HSI分量
void CImage_ProcessingView::OnHsi()
{
// TODO: 在此添加命令处理程序代码
if(m_Image.IsNull()) return;//判断图像是否为空,如果对空图像进行操作会出现未知的错误
int w=m_Image.GetWidth();//获得图像的宽度
int h=m_Image.GetHeight();//获得图像的高度
Cchoose mychoose=new Cchoose();
CStringArray strArray;
strArray.Add(L"H");
strArray.Add(L"S");
strArray.Add(L"I");
mychoose.strArray.Copy(strArray);
mychoose.DoModal();
//this->MessageBox(mychoose.chooseResult);
CString choose = mychoose.chooseResult;
//this->MessageBox(choose)
double value=0;
if(choose.Compare(L"H")==0)
{
for (int j=0;j<h;j++)
{
for (int k=0;k<w;k++)
{
double angle1=((m_Image.m_pBits[2][j][k]-m_Image.m_pBits[1][j][k])+(m_Image.m_pBits[2][j][k]-m_Image.m_pBits[0][j][k]))/2.0;
double angle2=sqrt((double)((m_Image.m_pBits[2][j][k]-m_Image.m_pBits[1][j][k])*(m_Image.m_pBits[2][j][k]-m_Image.m_pBits[1][j][k])+(m_Image.m_pBits[2][j][k]-m_Image.m_pBits[0][j][k])*(m_Image.m_pBits[1][j][k]-m_Image.m_pBits[0][j][k])));
double angle=acos(angle1/angle2);
if(m_Image.m_pBits[0][j][k]>m_Image.m_pBits[1][j][k])
{
angle=360-angle;
}
m_Image.m_pBits[0][j][k]=m_Image.m_pBits[1][j][k]=m_Image.m_pBits[2][j][k]=angle*(255.0/360.0);
}
}
}
else if(choose.Compare(L"S")==0)
{
int min;
for (int j=0;j<h;j++)
{
for (int k=0;k<w;k++)
{
min=m_Image.m_pBits[0][j][k];
for(int m=0;m<3;m++)
{
if(m_Image.m_pBits[m][j][k]<min)
min=m_Image.m_pBits[m][j][k];
}
value=1.0-(3.0/(m_Image.m_pBits[0][j][k]+m_Image.m_pBits[1][j][k]+m_Image.m_pBits[2][j][k]))*min;
m_Image.m_pBits[0][j][k]=m_Image.m_pBits[1][j][k]=m_Image.m_pBits[2][j][k]=value*255;
}
}
}
else if(choose.Compare(L"I")==0)
{
for (int j=0;j<h;j++)
{
for (int k=0;k<w;k++)
{
value=(m_Image.m_pBits[0][j][k]+m_Image.m_pBits[1][j][k]+m_Image.m_pBits[2][j][k])/3;
m_Image.m_pBits[0][j][k]=m_Image.m_pBits[1][j][k]=m_Image.m_pBits[2][j][k]=value;
}
}
}
Invalidate(1); //强制调用ONDRAW函数,ONDRAW会绘制图像
}
void CImage_ProcessingView::OnRatio()
{
//设置灰度分辨率选项
Cchoose mychoose=new Cchoose();
CStringArray strArray;
strArray.Add(L"128");
strArray.Add(L"64");
strArray.Add(L"32");
strArray.Add(L"16");
strArray.Add(L"8");
strArray.Add(L"4");
strArray.Add(L"2");
mychoose.strArray.Copy(strArray);
mychoose.DoModal();
//this->MessageBox(mychoose.chooseResult);
int fbl = _ttoi(mychoose.chooseResult);
if(m_Image.IsNull()) return;//判断图像是否为空,如果对空图像进行操作会出现未知的错误
int w=m_Image.GetWidth();//获得图像的宽度
int h=m_Image.GetHeight();//获得图像的高度
//获取灰度图像
BYTE aa;
for (int j=0;j<h;j++)
{
for (int k=0;k<w;k++)
{
aa= (m_Image.m_pBits[0][j][k]+m_Image.m_pBits[1][j][k]+m_Image.m_pBits[2][j][k])/3.0;
for(int m=0;m<256;m+=256/fbl)
{
if(aa>=m&&aa<(m+256/fbl))
{
m_Image.m_pBits[0][j][k]=m;
m_Image.m_pBits[1][j][k]=m;
m_Image.m_pBits[2][j][k]=m;
break;
}
}
}
}
Invalidate(1); //强制调用ONDRAW函数,ONDRAW会绘制图像
}
4:显示直方图
void CImage_ProcessingView::OnXszft()
{
// TODO: 在此添加命令处理程序代码
if(m_Image.IsNull()) return;//判断图像是否为空,如果对空图像进行操作会出现未知的错误
int w=m_Image.GetWidth();//获得图像的宽度
int h=m_Image.GetHeight();//获得图像的高度
double a[256]={};
int gray=0;
//求个数
for (int j=0;j<h;j++)
{
for (int k=0;k<w;k++)
{
gray=(m_Image.m_pBits[0][j][k]+m_Image.m_pBits[1][j][k]+m_Image.m_pBits[2][j][k])/3.0;
a[gray]++;
}
}
//归一化
CString mystr;
for(int i=0;i<256;i++)
{
a[i]=a[i]/((double)(w*h));
//this->MessageBox(mystr.Format(_T("%f"),a[i]));
}
//显示绘制的直方图
Histogram histogram=new Histogram();
memcpy(histogram.value,a,sizeof(a));
histogram.DoModal();
}
void Histogram::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
CDC *pDC=m_picDraw.GetDC();
CPen newPen; // 用于创建新画笔
CPen *pOldPen; // 用于存放旧画笔
CBrush newBrush; // 用于创建新画刷
CBrush *pOldBrush; // 用于存放旧画刷
// 创建黑色新画刷
newBrush.CreateSolidBrush(RGB(0,0,0));
// 选择新画刷,并将旧画刷的指针保存到pOldBrush
pOldBrush = pDC->SelectObject(&newBrush);
// 以黑色画刷为绘图控件填充黑色,形成黑色背景
// 创建实心画笔,粗度为1,颜色为绿色
newPen.CreatePen(PS_SOLID, 1, RGB(0,0,255));
// 选择新画笔,并将旧画笔的指针保存到pOldPen
pOldPen = pDC->SelectObject(&newPen);
for(int i=0;i<256;i++)
{
pDC->MoveTo(10+2*i,300);
pDC->LineTo(10+2*i,300-4000*(value[i]));
}
pDC->SelectObject(pOldPen);
pDC->SelectObject(pOldBrush);
newBrush.DeleteObject();
newPen.DeleteObject();
}
5:直方图均衡化
void CImage_ProcessingView::OnJhh()
{
// TODO: 在此添加命令处理程序代码
if(m_Image.IsNull()) return;//判断图像是否为空,如果对空图像进行操作会出现未知的错误
int w=m_Image.GetWidth();//获得图像的宽度
int h=m_Image.GetHeight();//获得图像的高度
double a[256]={};
int result[256]={};
int gray=0;
//求个数
for (int j=0;j<h;j++)
{
for (int k=0;k<w;k++)
{
gray=(m_Image.m_pBits[0][j][k]+m_Image.m_pBits[1][j][k]+m_Image.m_pBits[2][j][k])/3.0;
a[gray]++;
}
}
for(int i=0;i<256;i++)
{
a[i]=a[i]/((double)(w*h));
//this->MessageBox(mystr.Format(_T("%f"),a[i]));
}
for(int i=0;i<256;i++)
{
double sum=0;
for(int j=0;j<=i;j++)
{
sum+=a[j];
}
result[i]=sum*255;
}
//图片赋值
for (int j=0;j<h;j++)
{
for (int k=0;k<w;k++)
{
gray=(int)((m_Image.m_pBits[0][j][k]+m_Image.m_pBits[1][j][k]+m_Image.m_pBits[2][j][k])/3.0);
m_Image.m_pBits[0][j][k]=m_Image.m_pBits[1][j][k]=m_Image.m_pBits[2][j][k]=result[gray];
}
}
Invalidate(1); //强制调用ONDRAW函数,ONDRAW会绘制图像
}
6:全局阈值算法分割图像
void CImage_ProcessingView::Onjbqjfzsf()
{
// TODO: 在此添加命令处理程序代码
if(m_Image.IsNull()) return;//判断图像是否为空,如果对空图像进行操作会出现未知的错误
int w=m_Image.GetWidth();//获得图像的宽度
int h=m_Image.GetHeight();//获得图像的高度
double gray=0;
double avg=0;
double newAvg=0;
for (int j=0;j<h;j++)
{
for (int k=0;k<w;k++)
{
gray=(m_Image.m_pBits[0][j][k]+m_Image.m_pBits[1][j][k]+m_Image.m_pBits[2][j][k])/3;
avg+=gray;
}
}
avg=avg/(w*h);
newAvg=avg;
do
{
avg=newAvg;
double num1=0;
double num2=0;
double sum1=0,sum2=0;
for (int j=0;j<h;j++)
{
for (int k=0;k<w;k++)
{
gray=(m_Image.m_pBits[0][j][k]+m_Image.m_pBits[1][j][k]+m_Image.m_pBits[2][j][k])/3;
if(gray<avg)
{
sum1+=gray;
num1++;
}
else
{
sum2+=gray;
num2++;
}
}
}
newAvg=(sum1/num1+sum2/num2)/2;
}while(abs(newAvg-avg)>5);
for (int j=0;j<h;j++)
{
for (int k=0;k<w;k++)
{
gray=(m_Image.m_pBits[0][j][k]+m_Image.m_pBits[1][j][k]+m_Image.m_pBits[2][j][k])/3;
if(gray<newAvg)
{
m_Image.m_pBits[0][j][k]=m_Image.m_pBits[1][j][k]=m_Image.m_pBits[2][j][k]=0;
}
else
{
m_Image.m_pBits[0][j][k]=m_Image.m_pBits[1][j][k]=m_Image.m_pBits[2][j][k]=255;
}
}
}
Invalidate(1);
}