www.pudn.com > dbnn.rar > DBNNView.cpp, change:2004-02-24,size:17209b
// DBNNView.cpp : implementation of the CDBNNView class // #include "stdafx.h" #include "DBNN.h" #include "DBNNDoc.h" #include "DBNNView.h" #include "math.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif //int min(int r,int g, int b); ///////////////////////////////////////////////////////////////////////////// // CDBNNView IMPLEMENT_DYNCREATE(CDBNNView, CView) BEGIN_MESSAGE_MAP(CDBNNView, CView) //{{AFX_MSG_MAP(CDBNNView) ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDBNNView construction/destruction CDBNNView::CDBNNView():m_R(0),m_G(0),m_B(0),m_tch(0) { // TODO: add construction code here } CDBNNView::~CDBNNView() { } BOOL CDBNNView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs return CView::PreCreateWindow(cs); } ///////////////////////////////////////////////////////////////////////////// // CDBNNView drawing void CDBNNView::OnDraw(CDC* pDC) { // 显示等待光标 BeginWaitCursor(); // 获取文档 CDBNNDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here // 获取DIB HDIB hDIB = pDoc->GetHDIB(); // 判断DIB是否为空 if (hDIB != NULL) { LPBYTE lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB); // 获取DIB宽度 int cxDIB = (int) pDoc->m_clsDIB.DIBWidth(lpDIB); // 获取DIB高度 int cyDIB = (int) pDoc->m_clsDIB.DIBHeight(lpDIB); ::GlobalUnlock((HGLOBAL) hDIB); CRect rcDIB; rcDIB.top = rcDIB.left = 0; rcDIB.right = cxDIB; rcDIB.bottom = cyDIB; CRect rcDest; // 判断是否是打印 /*if (pDC->IsPrinting()) { // 是打印,计算输出图像的位置和大小,以便符合页面 // 获取打印页面的水平宽度(象素) int cxPage = pDC->GetDeviceCaps(HORZRES); // 获取打印页面的垂直高度(象素) int cyPage = pDC->GetDeviceCaps(VERTRES); // 获取打印机每英寸象素数 int cxInch = pDC->GetDeviceCaps(LOGPIXELSX); int cyInch = pDC->GetDeviceCaps(LOGPIXELSY); // 计算打印图像大小(缩放,根据页面宽度调整图像大小) rcDest.top = rcDest.left = 0; rcDest.bottom = (int)(((double)cyDIB * cxPage * cyInch) / ((double)cxDIB * cxInch)); rcDest.right = cxPage; // 计算打印图像位置(垂直居中) int temp = cyPage - (rcDest.bottom - rcDest.top); rcDest.bottom += temp/2; rcDest.top += temp/2; } else // 非打印 {*/ // 不必缩放图像 rcDest = rcDIB; // } // 输出DIB pDoc->m_clsDIB.PaintDIB(pDC->m_hDC, &rcDest, pDoc->GetHDIB(), &rcDIB, pDoc->GetDocPalette()); } // 恢复正常光标 EndWaitCursor(); } ///////////////////////////////////////////////////////////////////////////// // CDBNNView printing BOOL CDBNNView::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); } void CDBNNView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing } void CDBNNView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing } ///////////////////////////////////////////////////////////////////////////// // CDBNNView diagnostics #ifdef _DEBUG void CDBNNView::AssertValid() const { CView::AssertValid(); } void CDBNNView::Dump(CDumpContext& dc) const { CView::Dump(dc); } CDBNNDoc* CDBNNView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDBNNDoc))); return (CDBNNDoc*)m_pDocument; } #endif //_DEBUG void CDBNNView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default // 获取文档 CDBNNDoc* pDoc = GetDocument(); // 保存当前选中点坐标 pDoc->m_ptPoint_I = point; CView::OnLButtonDown(nFlags, point); } /************************************************************************* * * 函数名称: * Roberts() * * 参数: * HDIB hDIB - 待处理的DIB * * 返回值: * void - 无返回值 * * 说明: * 对图像进行罗伯特交叉算子的边缘检测 * ************************************************************************/ void Roberts(HDIB hDIB,CDBNNDoc* pDoc) { // 循环变量 LONG i; LONG j; LONG k; LONG l; // 指向DIB的指针 LPBYTE lpDIB; // 指向DIB象素指针 LPBYTE lpDIBBits; // 锁定DIB lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB); // 找到DIB图像象素起始位置 lpDIBBits = pDoc->m_clsDIB.FindDIBBits(lpDIB); // 判断是否是24-bpp位图 if (pDoc->m_clsDIB.DIBBitCount(lpDIB) != 24) { // 提示用户 // MessageBox("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK); // 解除锁定 ::GlobalUnlock((HGLOBAL) hDIB); // 返回 return; } // 更改光标形状 pDoc->BeginWaitCursor(); // DIB的宽度 LONG lWidth = pDoc->m_clsDIB.DIBWidth(lpDIB); // DIB的高度 LONG lHeight = pDoc->m_clsDIB.DIBHeight(lpDIB); // 计算图像每行的字节数 LONG lLineBytes = WIDTHBYTES(lWidth * 24); // 不能用char,也不能用::strcpy() unsigned char* m_temp; m_temp = new unsigned char [lLineBytes * lHeight]; // 中间变量 int v_r_v, v_g_v, v_b_v, g_v; int v_r_h, v_g_h, v_b_h, g_h; // 复制图象数据到中间缓存 for (i = 0; i < lLineBytes * lHeight; i++) m_temp[i] = *(lpDIBBits + i); // 2X2 模版 for (i = 0; i < lWidth; i++) //被处理像素在i列 { for (j = 0; j < lHeight; j++) //被处理像素在j行 { v_r_v = v_g_v = v_b_v = v_r_h = v_g_h = v_b_h = 0; for (k = i - 1; k < i + 1; k++) //2*2模版 { for (l = j - 1; l < j + 1; l++) { // 防止内存溢出 if (k >= 0 && l >= 0 && k < lWidth && l < lHeight) { // 检测模版 if (k == i - 1 && l == j - 1) g_v = 1; else if (k == i && l == j) g_v = -1; else g_v = 0; if(k == i - 1 && l == j) g_h = -1; else if (k == i && l == j - 1) g_h = 1; else g_h = 0; v_r_v += *(lpDIBBits + l * lLineBytes + k * 3) * g_v; v_r_h += *(lpDIBBits + l * lLineBytes + k * 3) * g_h; v_g_v += *(lpDIBBits + l * lLineBytes + k * 3 + 1) * g_v; v_g_h += *(lpDIBBits + l * lLineBytes + k * 3 + 1) * g_h; v_b_v += *(lpDIBBits + l * lLineBytes + k * 3 + 2) * g_v; v_b_h += *(lpDIBBits + l * lLineBytes + k * 3 + 2) * g_h; } } } m_temp[j * lLineBytes + i * 3] = (int)sqrt(v_r_v * v_r_v + v_r_h * v_r_h); m_temp[j * lLineBytes + i * 3 + 1] = (int)sqrt(v_g_v * v_g_v + v_g_h * v_g_h); m_temp[j * lLineBytes + i * 3 + 2] = (int)sqrt(v_b_v * v_b_v + v_b_h * v_b_h); } } // 回存处理结果到DIB for(i = 0; i < lLineBytes * lHeight; i++) *(lpDIBBits + i) = m_temp[i]; // 解除锁定 ::GlobalUnlock((HGLOBAL) hDIB); // 释放内存 delete[] m_temp; // 恢复光标 pDoc->EndWaitCursor(); } /***************************************/ /* color代表颜色数 x代表输入训练样本的均值 w代表权矩阵 delta代表学习速率 c0、c1代表神经元加权系数 B_F代表神经元基函数 tp代表教师信号 S_F代表子神经元的判决函数 Sum_F代表判决函数的加权和 S2代表样本的方差 */ void CDBNNView::DBNN(int X[],double pass[],double s2[]) { double w[2*(color+1)][3]={0}; double delta=0.01; int c0=100; int c1=50; double mark5=0; double mark1=0; double mark2=0; int mark3=1; int mark4=1; double x[color][3]; int i,j,k,l,m,n,o; int tp[color+1]; double B_F[color+1][2]; double S_F[color+1][2]; double Sum_F[color+1]; double S2[color]={0}; for (i=0;i<color;i++) { for(j=0;j<3;j++) { x[i][j]=*X; X++; //?test //CString str; //str.Format("%f",x[i][j]); //MessageBox(str, "test", MB_OK); //?test; } } for(i=0;i<color;i++) { S2[i]=*s2; s2++; } while(mark4) { mark4=0; for(m=0;m<2;m++) { for(l=0;l<color;l++) { tp[l]=l; mark3=1; while(mark3) { for(i=0;i<color+1;i++) { for(k=0;k<2;k++) { B_F[i][k]=0; S_F[i][k]=0; } Sum_F[i]=0; } mark1=0; mark2=0; for(i=0;i<color+1;i++) { for(k=0;k<2;k++) { for(j=0;j<3;j++) { B_F[i][k]=mark1-(x[l][j]-w[i*2+k][j])*(x[l][j]-w[i*2+k][j])/2; mark1=B_F[i][k]; } mark1=0; S_F[i][k]=exp(B_F[i][k]/100);///S2[l]); } Sum_F[i]=c0*S_F[i][0]+c1*S_F[i][1]; //?test //CString str; //str.Format("%f",Sum_F[i]); //MessageBox(str, "test", MB_OK); //?test } mark3=0; for(i=l+1;i<color+1;i++) { if(Sum_F[l]<=Sum_F[i]) { for(j=0;j<3;j++) { w[l*2+m][j]=w[l*2+m][j]+delta*(x[l][j]-w[l*2+m][j]); w[i*2+m][j]=w[i*2+m][j]-delta*(x[l][j]-w[i*2+m][j]); mark3=1; mark4=1; //?test // CString str; //str.Format("%f",w[l*2+m][j]); //MessageBox(str, "test", MB_OK); //?test } } if(mark3)break; } //?test //CString str; //str.Format("%f",Sum_F[i]); //MessageBox(str, "test", MB_OK); //?test if(mark3!=1) { for(i=0;i<l;i++) { if(Sum_F[l]<=Sum_F[i]) { for(j=0;j<3;j++) { w[l*2+m][j]=w[l*2+m][j]+delta*(x[l][j]-w[l*2+m][j]); w[i*2+m][j]=w[i*2+m][j]-delta*(x[l][j]-w[i*2+m][j]); mark3=1; mark4=1; } } if(mark3)break; } } /* for(i=0;i<color+1;i++) { for(k=0;k<2;k++) { for(j=0;j<3;j++) { //?test CString str; str.Format("%f",w[i*2+k][j]); MessageBox(str, "test", MB_OK); //?test } } } */ } } } } for(i=0;i<2*(color+1);i++) { for(j=0;j<3;j++) { pass[i*3+j]=w[i][j]; } } //?test //for(i=0;i<18;i++) //{ //CString str; //str.Format("%f",pass[i]); // MessageBox(str, "test", MB_OK); //} //?test } /**********************************************************/ void CDBNNView::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default // 获取文档 CDBNNDoc* pDoc = GetDocument(); // 保存当前选中点坐标 pDoc->m_ptPoint_II = point; CDC* pDC = GetDC(); CPoint tmpPoint; int maxX = pDoc->m_ptPoint_I.x; int minX = point.x; int maxY = pDoc->m_ptPoint_I.y; int minY = point.y; COLORREF clrT; if (maxX < minX) { int tmp = maxX; maxX = minX; minX = tmp; } if (maxY < minY) { int tmp = maxY; maxY = minY; minY= tmp; } m_R = 0; m_G = 0; m_B = 0; for (int i=minY; i<=maxY; i++) for (int j=minX; j<=maxX; j++) { clrT = pDC->GetPixel(CPoint(j,i)); m_R += GetRValue(clrT); m_G += GetGValue(clrT); m_B += GetBValue(clrT); } long num = ((maxX-minX+1)*(maxY-minY+1)); m_R /= num; m_G /= num; m_B /= num; //计算方差 double deta=0.0,detaR=0.0,detaG=0.0,detaB=0.0; for (i=minY; i<=maxY; i++) for (int j=minX; j<=maxX; j++) { clrT = pDC->GetPixel(CPoint(j,i)); detaR += (m_R-GetRValue(clrT))*(m_R-GetRValue(clrT)); detaG += (m_G-GetGValue(clrT))*(m_G-GetGValue(clrT)); detaB += (m_B-GetBValue(clrT))*(m_B-GetBValue(clrT)); } detaR = sqrt(detaR/num); detaG = sqrt(detaG/num); detaB = sqrt(detaB/num); deta = detaR + detaG + detaB; long r,g,b; r = m_R; g = m_G; b = m_B; m_R = (long)(255*r/(r+g+b)); m_G = (long)(255*g/(r+g+b)); m_B = 255-m_R-m_G; //标出选择框 pDC->MoveTo(minX,minY); pDC->LineTo(maxX,minY); pDC->LineTo(maxX,maxY); pDC->LineTo(minX,maxY); pDC->LineTo(minX,minY); //输入教师信号 CStuDlg dlg; dlg.DoModal(); m_tch = dlg.m_tch; m_RGB[m_tch*3] = (int)m_B; m_RGB[m_tch*3+1] = (int)m_G; m_RGB[m_tch*3+2] = (int)m_R; m_deta[m_tch] = deta; // 报告当前平均RGB值 CString strRGB; strRGB.Format("当前点平均颜色值:\r\n\r\n R = %d\r\n G = %d\r\n B = %d\r\n deta = %f\r\n tch = %d\r\n num = %d\r\n", m_R, m_G, m_B,deta,m_tch,num); MessageBox(strRGB, "返回结果", MB_OK); //图像处理:通过指向CDBNNDoc类实例的指针pDoc进行处理, //因为CDBNNView类的OnDraw函数显示的是CDBNNDoc类中存有 //的图像,在图像重绘后,修改后的图像就得到了显示 //调用Roberts算法进行测试 /*Roberts(pDoc->m_hDIB,pDoc); Invalidate();*/ if (m_tch == color - 1) { /* //?test strRGB.Format("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",m_RGB[0],m_RGB[1],m_RGB[2],m_RGB[3],m_RGB[4],m_RGB[5],m_RGB[6],m_RGB[7],m_RGB[8],m_RGB[9],m_RGB[10],m_RGB[11],m_RGB[12],m_RGB[13],m_RGB[14]); MessageBox(strRGB, "m_RGB", MB_OK);//?test*/ Sort(); DBNN(m_RGB,m_w,m_deta); dis_f(m_w,m_deta); Invalidate(); /*//?show strRGB = ""; for(int i=0; i<2*(color+1)*3;i++) { CString str; str.Format("%d,",m_w[i]); strRGB += str; } MessageBox(strRGB, "m_RGB", MB_OK);//?show*/ } CView::OnLButtonUp(nFlags, point); } void CDBNNView::Sort() { // 获取文档 CDBNNDoc* pDoc = GetDocument(); // 指向DIB的指针 LPBYTE lpDIB; // 锁定DIB lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) pDoc->m_hDIB); // 指向DIB象素指针 LPBYTE lpDIBBits; // 找到DIB图像象素起始位置 lpDIBBits = pDoc->m_clsDIB.FindDIBBits(lpDIB); // DIB的宽度 LONG lWidth = pDoc->m_clsDIB.DIBWidth(lpDIB); // DIB的高度 LONG lHeight = pDoc->m_clsDIB.DIBHeight(lpDIB); // 计算图像每行的字节数 LONG lLineBytes = WIDTHBYTES(lWidth * 24); int r,g,b; for (int h=0; h<lHeight; h++) { for (int w=0; w<lWidth; w++) { b = lpDIBBits[h*lLineBytes+w*3]; g = lpDIBBits[h*lLineBytes+w*3+1]; r = lpDIBBits[h*lLineBytes+w*3+2]; /*/?test CString strRGB; strRGB.Format("r = %d,g = %d,b= %d", r,g,b); MessageBox(strRGB, "test", MB_OK); *///?test if (r==g && g==b && b==0); else { lpDIBBits[h*lLineBytes+w*3] = 255*(1.0*b/(r+g+b)); lpDIBBits[h*lLineBytes+w*3+1] = 255*(1.0*g/(r+g+b)); lpDIBBits[h*lLineBytes+w*3+2] = (255 -lpDIBBits[h*lLineBytes+w*3] -lpDIBBits[h*lLineBytes+w*3+1]); } /*/?test strRGB.Format("r = %d,g = %d,b= %d", lpDIBBits[h*lLineBytes+w*3+2] ,lpDIBBits[h*lLineBytes+w*3+1] ,lpDIBBits[h*lLineBytes+w*3]); MessageBox(strRGB, "test", MB_OK); *///?test } } /* double B_F[color+1][2]; double S_F[color+1][2]; double Sum_F[color+1]; for(l=0;l<color;l++) { for(i=0;i<color+1;i++) { for(k=0;k<2;k++) { B_F[i][k]=0; S_F[i][k]=0; } Sum_F[i]=0; } for(i=0;i<color+1;i++) { for(k=0;k<2;k++) { for(j=0;j<3;j++) { B_F[i][k]=mark1-(x[l][j]-w[i*2+k][j])*(x[l][j]-w[i*2+k][j])/2; mark1=B_F[i][k]; } mark1=0; S_F[i][k]=exp(B_F[i][k]/S2[l]); } Sum_F[i]=c0*S_F[i][0]+c1*S_F[i][1]; cout<<Sum_F[i]<<" "; } cout<<endl; } */ // 解除锁定 ::GlobalUnlock((HGLOBAL) pDoc->m_hDIB); } void CDBNNView::dis_f(double *pass,double *S2) { double B_F[color+1][2] = {0}; double S_F[color+1][2] = {0}; double Sum_F[color+1] = {0}; double mark1 = 0.0; int c0 = 100; int c1 = 50; // 获取文档 CDBNNDoc* pDoc = GetDocument(); // 指向DIB的指针 LPBYTE lpDIB; // 锁定DIB lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) pDoc->m_hDIB); // 指向DIB象素指针 LPBYTE lpDIBBits; // 找到DIB图像象素起始位置 lpDIBBits = pDoc->m_clsDIB.FindDIBBits(lpDIB); // DIB的宽度 LONG lWidth = pDoc->m_clsDIB.DIBWidth(lpDIB); // DIB的高度 LONG lHeight = pDoc->m_clsDIB.DIBHeight(lpDIB); // 计算图像每行的字节数 // LONG lLineBytes = WIDTHBYTES(lWidth * 24); unsigned char *x = lpDIBBits; for(int m=0;m<lWidth*lHeight;m++) { for(int i=0;i<color+1;i++) { for(int k=0;k<2;k++) { B_F[i][k]=0; S_F[i][k]=0; } Sum_F[i]=0; } for(i=0;i<color+1;i++) { for(int k=0;k<2;k++) { for(int j=0;j<3;j++) { B_F[i][k]=mark1-(*(x+j)-pass[i*6+k*3+j])*(*(x+j)-pass[i*6+k*3+j])/2; mark1=B_F[i][k]; } mark1=0; S_F[i][k]=exp(B_F[i][k]/100);///S2[i]); //?test //CString str; //str.Format("%f",S_F[i][k]); //MessageBox(str, "test", MB_OK); //?test } Sum_F[i]=c0*S_F[i][0]+c1*S_F[i][1]; // cout<<Sum_F[i]<<" "; } //?test //CString str; //str.Format("%f,%f,%f", Sum_F[0],Sum_F[1],Sum_F[2]); //MessageBox(str, "test", MB_OK); //?test for(i=1;i<color+1;i++) { if(Sum_F[i]>Sum_F[0]) { for (int bgr=0;bgr<3;bgr++) *(x+bgr)=255; } } x += 3; } // 解除锁定 ::GlobalUnlock((HGLOBAL) pDoc->m_hDIB); } /* int min(int r,int g,int b) { if(r>g) r=g; if(r>b) r=b; return r; } */