ED256View.cpp
上传用户:dfwb928
上传日期:2013-04-20
资源大小:228k
文件大小:16k
- //////////////////////////////////////////////////////////////////
- // CED256View class (17/10/2000)
- // Author: James Matthews
- //
- // Implements a simple edge detection algorithm and
- // prototyping system.
- //
- // Written for Generation5 (http://www.generation5.org/)
- //
- // See http://www.generation5.org/vision.shtml
- // http://www.generation5.org/edgedetect.shtml for details.
- //
- #include "stdafx.h"
- #include "ED256.h"
- #include "ED256Doc.h"
- #include "ED256View.h"
- #include "Mainfrm.h"
- #include <math.h>
- #include <memory.h>
- #include "FilterDlg.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CED256View
- IMPLEMENT_DYNCREATE(CED256View, CView)
- BEGIN_MESSAGE_MAP(CED256View, CView)
- //{{AFX_MSG_MAP(CED256View)
- ON_COMMAND(ID_EDIT_EDGEDETECT, OnEditEdgeDetect)
- ON_COMMAND(ID_COLOURTYPE, OnColourType)
- ON_COMMAND(ID_FORMULA, OnFormula)
- ON_COMMAND(ID_EDIT_FORMULATYPE_DIFFERENCEAND, OnEditFormulatypeDifferenceand)
- ON_COMMAND(ID_EDIT_FORMULATYPE_DIFFERENCEOR, OnEditFormulatypeDifferenceor)
- ON_COMMAND(ID_EDIT_FORMULATYPE_SUMMATION, OnEditFormulatypeSummation)
- ON_COMMAND(ID_INVERSE, OnInverse)
- ON_COMMAND(ID_FILTER, OnFilter)
- ON_UPDATE_COMMAND_UI(ID_COLOURTYPE, OnUpdateColourtype)
- ON_UPDATE_COMMAND_UI(ID_INVERSE, OnUpdateInverse)
- ON_COMMAND(ID_EDIT_OUTPUT_BLACKANDWHITE, OnEditOutputBlackandwhite)
- ON_COMMAND(ID_EDIT_OUTPUT_COLOUR, OnEditOutputColour)
- ON_UPDATE_COMMAND_UI(ID_EDIT_OUTPUT_BLACKANDWHITE, OnUpdateEditOutputBlackandwhite)
- ON_UPDATE_COMMAND_UI(ID_EDIT_OUTPUT_COLOUR, OnUpdateEditOutputColour)
- ON_UPDATE_COMMAND_UI(ID_EDIT_FORMULATYPE_DIFFERENCEAND, OnUpdateEditFormulatypeDifferenceand)
- ON_UPDATE_COMMAND_UI(ID_EDIT_FORMULATYPE_DIFFERENCEOR, OnUpdateEditFormulatypeDifferenceor)
- ON_UPDATE_COMMAND_UI(ID_EDIT_FORMULATYPE_SUMMATION, OnUpdateEditFormulatypeSummation)
- ON_WM_ERASEBKGND()
- ON_COMMAND(ID_EDIT_PROTOTYPING, OnEditPrototyping)
- ON_COMMAND(ID_CHANGERESOLUTION, OnChangeResolution)
- ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
- ON_UPDATE_COMMAND_UI(ID_RES_LOW, OnUpdateResLow)
- ON_UPDATE_COMMAND_UI(ID_RES_MEDIUM, OnUpdateResMedium)
- ON_UPDATE_COMMAND_UI(ID_RES_HIGH, OnUpdateResHigh)
- //}}AFX_MSG_MAP
- ON_COMMAND_RANGE(ID_RES_LOW, ID_RES_HIGH, OnResolution)
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CED256View construction/destruction
- CED256View::CED256View() {
- m_iFormula = 0;
- m_iResolution = 4;
- m_bColour = true;
- m_bInverse = false;
- m_crPlot = RGB(0,0,0);
- m_crNoPlot = RGB(255,255,255);
- m_fFilter[0] = 1/6.0f;
- m_fFilter[1] = 2/3.0f;
- m_fFilter[2] = 1/6.0f;
- m_fFilter[3] = 2/3.0f;
- m_fFilter[4] = -10/3.0f;
- m_fFilter[5] = 2/3.0f;
- m_fFilter[6] = 1/6.0f;
- m_fFilter[7] = 2/3.0f;
- m_fFilter[8] = 1/6.0f;
- m_crProtoColours[0] = RGB(255,0,0);
- m_crProtoColours[1] = RGB(128,0,0);
- m_crProtoColours[2] = RGB(0,255,0);
- m_crProtoColours[3] = RGB(0,128,0);
- m_crProtoColours[4] = RGB(0,0,255);
- m_crProtoColours[5] = RGB(0,0,128);
- m_crProtoColours[6] = RGB(255,0,255);
- m_crProtoColours[7] = RGB(128,0,128);
- m_crProtoColours[8] = RGB(0,0,0);
- m_crProtoColours[9] = RGB(255,255,255);
- }
- CED256View::~CED256View() {}
- BOOL CED256View::PreCreateWindow(CREATESTRUCT& cs) {
- return CView::PreCreateWindow(cs);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CED256View drawing
- void CED256View::OnDraw(CDC* pDC) {
- CED256Doc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- CRect rect;
- GetClientRect(&rect);
- CDC dc;
- CBitmap bmp, *oldbmp;
- dc.CreateCompatibleDC(pDC);
- bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
- oldbmp = dc.SelectObject(&bmp);
-
- dc.FillSolidRect(rect, RGB(255,255,255));
- int cxDIB = 0, cyDIB = 0;
- HDIB hDIB = pDoc->GetHDIB();
- if (hDIB) {
- LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
- cxDIB = (int) ::DIBWidth(lpDIB);
- cyDIB = (int) ::DIBHeight(lpDIB);
- ::GlobalUnlock((HGLOBAL) hDIB);
- CRect rcDIB;
- rcDIB.top = rcDIB.left = 0;
- rcDIB.right = cxDIB;
- rcDIB.bottom = cyDIB;
- CRect rcDest = rcDIB;
-
- if (cxDIB * 2 <= rect.Width() || !(HBITMAP(m_bmpEdges))) {
- ::PaintDIB(dc.m_hDC, &rcDest, hDIB,
- &rcDIB, pDoc->GetDocPalette());
- }
- }
- if ((HBITMAP)(m_bmpEdges)) {
- CDC cdc;
- CBitmap *oldbmp;
- cdc.CreateCompatibleDC(pDC);
- oldbmp = cdc.SelectObject(&m_bmpEdges);
-
- if (cxDIB * 2 < rect.Width()) {
- dc.BitBlt(cxDIB+1,0,cxDIB,cyDIB+m_iOffset,&cdc,0,0,SRCCOPY);
- } else {
- dc.BitBlt(0,0,cxDIB,cyDIB+m_iOffset,&cdc,0,0,SRCCOPY);
- }
- }
- pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dc,0,0,SRCCOPY);
- dc.SelectObject(oldbmp);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CED256View diagnostics
- #ifdef _DEBUG
- void CED256View::AssertValid() const {
- CView::AssertValid();
- }
- void CED256View::Dump(CDumpContext& dc) const {
- CView::Dump(dc);
- }
- CED256Doc* CED256View::GetDocument() {
- ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CED256Doc)));
- return (CED256Doc*)m_pDocument;
- }
- #endif //_DEBUG
- /////////////////////////////////////////////////////////////////////////////
- // CED256View message handlers
- void CED256View::OnEditEdgeDetect() {
- CWaitCursor wait;
-
- CMainFrame* pMfm = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- m_iOffset = 0;
- int thresh = pMfm->m_iThreshold;
-
- CDC sc1,sc2;
- CClientDC dc(this);
- sc1.CreateCompatibleDC(&dc);
- sc2.CreateCompatibleDC(&dc);
- CBitmap *src1old, bmsrc, *src2old;
- int cxDIB, cyDIB;
- CED256Doc* pDoc = GetDocument();
- HDIB hDIB = pDoc->GetHDIB();
- GetDIBSize(cxDIB, cyDIB);
- if ((HBITMAP)(m_bmpEdges)) m_bmpEdges.Detach();
-
- bmsrc.CreateCompatibleBitmap(&dc, cxDIB, cyDIB);
- m_bmpEdges.CreateCompatibleBitmap(&dc, cxDIB, cyDIB);
-
- src1old = sc1.SelectObject(&bmsrc);
- src2old = sc2.SelectObject(&m_bmpEdges);
- ::PaintDIB(sc1.m_hDC, &CRect(0,0,cxDIB,cyDIB), hDIB,
- &CRect(0,0,cxDIB,cyDIB), pDoc->GetDocPalette());
- float red, blue, green;
- // int red, blue, green;
- for (int i=1;i<cxDIB-1;i++) {
- for (int j=1;j<cyDIB-1;j++) {
- red = blue = green = 0;
- UpdateTotals(red, blue, green, m_fFilter[4], sc1.GetPixel(i,j));
- UpdateTotals(red, blue, green, m_fFilter[0], sc1.GetPixel(i-1,j));
- UpdateTotals(red, blue, green, m_fFilter[2], sc1.GetPixel(i+1,j));
- UpdateTotals(red, blue, green, m_fFilter[6], sc1.GetPixel(i,j-1));
- UpdateTotals(red, blue, green, m_fFilter[8], sc1.GetPixel(i,j+1));
- UpdateTotals(red, blue, green, m_fFilter[1], sc1.GetPixel(i-1,j-1));
- UpdateTotals(red, blue, green, m_fFilter[3], sc1.GetPixel(i+1,j-1));
- UpdateTotals(red, blue, green, m_fFilter[5], sc1.GetPixel(i-1,j+1));
- UpdateTotals(red, blue, green, m_fFilter[7], sc1.GetPixel(i+1,j+1));
-
- // Get the threshold value, and check whether any of the
- // values exceed the threshold value.
- if (Plot(int(red),int(green),int(blue),thresh)) {
- if (m_bColour)
- sc2.SetPixel(i,j, RGB(int(red),int(blue),int(green)));
- else sc2.SetPixel(i,j, m_crPlot);
- } else {
- sc2.SetPixel(i,j, m_crNoPlot);
- }
- }
- pMfm->PercentComplete(i / float(cxDIB) * 100);
- }
- CBrush br(RGB(0,0,0));
- sc2.FrameRect(&CRect(0,0,cxDIB, cyDIB), &br);
-
- sc1.SelectObject(src1old);
- sc2.SelectObject(src2old);
- Invalidate();
- pMfm->SetStatusMessage(AFX_IDS_IDLEMESSAGE);
- }
- void CED256View::UpdateTotals(float &r, float &g, float &b, float filter, COLORREF cr) {
- r += GetRValue(cr)*filter;
- b += GetBValue(cr)*filter;
- g += GetGValue(cr)*filter;
- }
- void CED256View::OnColourType() {
- m_bColour = !m_bColour;
- }
- void CED256View::OnFormula() {
- CMainFrame* pMfm = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- PullDownToolBar(pMfm->GetToolbar(), ID_FORMULA, IDR_FORMULA, m_iFormula);
- }
- void CED256View::PullDownToolBar(CToolBar *bar, UINT uButton, UINT uMenu, int bold) {
- // To be professional, get the index from the command ID.
- int ind = bar->CommandToIndex(uButton);
- if (ind == -1) return;
- CRect rect;
- bar->GetItemRect(ind,&rect);
- bar->ClientToScreen(&rect);
- CMenu menu;
- VERIFY(menu.LoadMenu(uMenu));
- CMenu* pPopup = menu.GetSubMenu(0);
- ASSERT(pPopup != NULL);
- if (bold > -1) SetMenuDefaultItem(pPopup->m_hMenu, bold, true);
-
- pPopup->TrackPopupMenu(TPM_LEFTALIGN, rect.TopLeft().x, rect.BottomRight().y, this);
- }
- bool CED256View::Plot(int r, int g, int b, int t) {
- switch(m_iFormula) {
- case 0: return (r > t && g > t && b > t);
- case 1: return (r > t || g > t || b > t);
- case 2: return (r+g+b > t);
- }
- return false;
- }
- void CED256View::OnEditFormulatypeDifferenceand() {
- m_iFormula = 0;
- }
- void CED256View::OnEditFormulatypeDifferenceor() {
- m_iFormula = 1;
- }
- void CED256View::OnEditFormulatypeSummation() {
- m_iFormula = 2;
- }
- void CED256View::OnInverse() {
- m_bInverse = !m_bInverse;
-
- if (!m_bInverse) {
- m_crPlot = RGB(0,0,0);
- m_crNoPlot = RGB(255,255,255);
- } else {
- m_crPlot = RGB(255,255,255);
- m_crNoPlot = RGB(0,0,0);
- }
- }
- void CED256View::OnFilter() {
- CFilterDlg dlg;
- dlg.SetFilter(&m_fFilter[0]);
- dlg.DoModal();
- m_fFilter[0] = dlg.m_fEdit1;
- m_fFilter[1] = dlg.m_fEdit2;
- m_fFilter[2] = dlg.m_fEdit3;
- m_fFilter[3] = dlg.m_fEdit4;
- m_fFilter[4] = dlg.m_fEdit5;
- m_fFilter[5] = dlg.m_fEdit6;
- m_fFilter[6] = dlg.m_fEdit7;
- m_fFilter[7] = dlg.m_fEdit8;
- m_fFilter[8] = dlg.m_fEdit9;
- }
- void CED256View::OnUpdateColourtype(CCmdUI* pCmdUI) {
- pCmdUI->SetCheck(m_bColour);
- }
- void CED256View::OnUpdateInverse(CCmdUI* pCmdUI) {
- pCmdUI->SetCheck(m_bInverse);
- }
- void CED256View::OnEditOutputBlackandwhite() {
- m_bColour = false;
- }
- void CED256View::OnEditOutputColour() {
- m_bColour = true;
- }
- void CED256View::OnInitialUpdate() {
- CView::OnInitialUpdate();
-
- if ((HBITMAP)(m_bmpEdges)) m_bmpEdges.Detach();
- }
- BOOL CED256View::OnEraseBkgnd(CDC* pDC) {
- return FALSE;
- }
- void CED256View::OnEditPrototyping() {
- CWaitCursor wait;
-
- CMainFrame* pMfm = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
- m_iOffset = 50;
- int thresh = pMfm->m_iThreshold;
-
- CDC sc1,sc2;
- CClientDC dc(this);
- sc1.CreateCompatibleDC(&dc);
- sc2.CreateCompatibleDC(&dc);
- CBitmap *src1old, bmsrc, *src2old;
- int cxDIB, cyDIB; // The width/height of the bitmap
- CED256Doc* pDoc = GetDocument();
- HDIB hDIB = pDoc->GetHDIB();
- GetDIBSize(cxDIB, cyDIB);
- if ((HBITMAP)(m_bmpEdges)) m_bmpEdges.Detach();
-
- bmsrc.CreateCompatibleBitmap(&dc, cxDIB, cyDIB);
- m_bmpEdges.CreateCompatibleBitmap(&dc, cxDIB, cyDIB + 100);
-
- src1old = sc1.SelectObject(&bmsrc);
- src2old = sc2.SelectObject(&m_bmpEdges);
- ::PaintDIB(sc1.m_hDC, &CRect(0,0,cxDIB,cyDIB), hDIB,
- &CRect(0,0,cxDIB,cyDIB), pDoc->GetDocPalette());
- ::PaintDIB(sc2.m_hDC, &CRect(0,0,cxDIB,cyDIB), hDIB,
- &CRect(0,0,cxDIB,cyDIB), pDoc->GetDocPalette());
- ////////////////////////////////////////////////
- // START PROTOTYPING
-
- _protoBmp samples[MAX_SAMPLES];
- _protoBmp prototypes[MAX_PROTOTYPES];
- int x,y;
- srand(unsigned(time(NULL)));
- pMfm->SetStatusMessage("Creating samples and prototypes...");
- // Initialize the samples
- for (int i=0;i<MAX_SAMPLES;i++) {
- x = rand() % cxDIB;
- y = rand() % cyDIB;
- for (int j=0;j<15;j++) {
- for (int k=0;k<15;k++) {
- samples[i].pixels[j][k] = char(sc1.GetPixel(x+j,y+k) & 0xFF);
- }
- }
- }
- // Initialize the prototypes
- for (i=0;i<MAX_PROTOTYPES;i++) {
- for (int j=0;j<15;j++) {
- for (int k=0;k<15;k++) {
- prototypes[i].pixels[j][k] = rand() % 255;
- }
- }
- }
- pMfm->SetStatusMessage("Competitive learning initialized...");
-
- int ind, k = 2, avg, bestavg, bestind, pavg[MAX_PROTOTYPES];
- for (i=0;i<MAX_PITERATIONS;i++) {
- memset(pavg,0,sizeof(avg));
- ind = rand() % MAX_SAMPLES;
- for (int j=0;j<MAX_PROTOTYPES;j++) {
- avg = 0;
- for (int k=0;k<15;k++) {
- for (int l=0;l<15;l++) {
- avg += abs(prototypes[j].pixels[k][l] - samples[ind].pixels[k][l]);
- }
- }
- pavg[j] = avg / (15*15);
- }
- bestind = 0; bestavg = pavg[0];
- for (j=1;j<MAX_PROTOTYPES;j++) {
- if (pavg[j] < bestavg) {
- bestind = j;
- bestavg = pavg[j];
- }
- }
- for (j=0;j<15;j++) {
- for (int k=0;k<15;k++) {
- prototypes[bestind].pixels[j][k] =
- (prototypes[bestind].pixels[j][k] - samples[ind].pixels[j][k]) / 100 * k + samples[ind].pixels[j][k];
- }
- }
- }
- // Create the picture.
- _protoBmp test;
- int minus = (m_iResolution/2);
- for (i=0;i<cxDIB+m_iResolution;i+=m_iResolution) {
- for (int j=0;j<cyDIB+m_iResolution;j+=m_iResolution) {
- // Get the pixels;
- for (int k=-7;k<8;k++) {
- for (int l=-7;l<8;l++) {
- test.pixels[k+7][l+7] = char(sc1.GetPixel(i+k,j+l) & 0xFF);
- }
- }
- for (int m=0;m<MAX_PROTOTYPES;m++) {
- avg = 0;
- for (int k=0;k<15;k++) {
- for (int l=0;l<15;l++) {
- avg += abs(prototypes[m].pixels[k][l] - test.pixels[k][l]);
- }
- }
-
- pavg[m] = avg / (15*15);
- }
- bestind = 0; bestavg = pavg[0];
- for (m=1;m<MAX_PROTOTYPES;m++) {
- if (pavg[m] < bestavg) {
- bestind = m;
- bestavg = pavg[m];
- }
- }
-
- sc2.FillSolidRect(i-minus,j-minus,m_iResolution,m_iResolution,m_crProtoColours[bestind]);
- }
- pMfm->PercentComplete(i/float(cxDIB)*100);
- }
- // Draw the prototypes and colours
-
- sc2.FillSolidRect(0,cyDIB,cxDIB,m_iOffset,RGB(255,255,255));
- for (i=0;i<MAX_PROTOTYPES;i++) {
- for (int j=0;j<15;j++) {
- for (int k=0;k<15;k++) {
- BYTE col = prototypes[i].pixels[j][k];
- sc2.SetPixel(j+(i*16),k+cyDIB+5,RGB(col,col,col));
- }
- }
- sc2.FillSolidRect(i*16,20+cyDIB+5,15,5,m_crProtoColours[i]);
- }
- CBrush br(RGB(0,0,0));
- sc2.FrameRect(&CRect(0,0,cxDIB, cyDIB), &br);
-
- sc1.SelectObject(src1old);
- sc2.SelectObject(src2old);
- Invalidate();
- pMfm->SetStatusMessage(AFX_IDS_IDLEMESSAGE);
- }
- void CED256View::OnChangeResolution() {
- int bold;
- switch (m_iResolution) {
- case 15: bold = 0; break;
- case 4: bold = 1; break;
- case 1: bold = 2; break;
- }
- CMainFrame* pMfm = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
-
- PullDownToolBar(&(pMfm->m_wndProtoBar), ID_CHANGERESOLUTION, IDR_RESOLUTION, bold);
- }
- void CED256View::OnResolution(UINT uID) {
- switch (uID) {
- case ID_RES_LOW: m_iResolution = 15; break;
- case ID_RES_MEDIUM: m_iResolution = 4; break;
- case ID_RES_HIGH: m_iResolution = 1; break;
- }
- }
- void CED256View::CopyBitmap() {
- CClientDC dc(this);
- CDC bmpdc, memdc;
- CBitmap bmp, *oldbmp1, *oldbmp2;
- int cxDIB, cyDIB; // The width/height of the bitmap
-
- GetDIBSize(cxDIB, cyDIB);
- bmpdc.CreateCompatibleDC(GetDC());
- memdc.CreateCompatibleDC(GetDC());
- bmp.CreateCompatibleBitmap(&dc, cxDIB, cyDIB);
- oldbmp1 = bmpdc.SelectObject(&m_bmpEdges);
- oldbmp2 = memdc.SelectObject(&bmp);
-
- CBrush br(RGB(0,0,0));
- memdc.BitBlt(0,0,cxDIB,cyDIB,&bmpdc,0,0,SRCCOPY);
- memdc.FrameRect(&CRect(0,0,cxDIB, cyDIB), &br);
- OpenClipboard();
- EmptyClipboard();
- SetClipboardData(CF_BITMAP, bmp.GetSafeHandle());
- CloseClipboard();
- bmp.Detach();
- bmpdc.SelectObject(oldbmp1);
- memdc.SelectObject(oldbmp2);
- }
- void CED256View::OnEditCopy() {
- CopyBitmap();
- }
- // FIXME: The DIB size really should be a class member!
- void CED256View::GetDIBSize(int &cx, int &cy) {
- CED256Doc* pDoc = GetDocument();
- HDIB hDIB = pDoc->GetHDIB();
- if (hDIB) {
- LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
- cx = (int) ::DIBWidth(lpDIB);
- cy = (int) ::DIBHeight(lpDIB);
- ::GlobalUnlock((HGLOBAL) hDIB);
- } else return;
- }
- // ON_COMMAND_UPDATE SCHTUFF
- void CED256View::OnUpdateEditOutputBlackandwhite(CCmdUI* pCmdUI) {
- pCmdUI->SetCheck(!m_bColour);
- }
- void CED256View::OnUpdateEditOutputColour(CCmdUI* pCmdUI) {
- pCmdUI->SetCheck(m_bColour);
- }
- void CED256View::OnUpdateEditFormulatypeDifferenceand(CCmdUI* pCmdUI) {
- pCmdUI->SetCheck(m_iFormula == 0);
- }
- void CED256View::OnUpdateEditFormulatypeDifferenceor(CCmdUI* pCmdUI) {
- pCmdUI->SetCheck(m_iFormula == 1);
- }
- void CED256View::OnUpdateEditFormulatypeSummation(CCmdUI* pCmdUI) {
- pCmdUI->SetCheck(m_iFormula == 2);
- }
- void CED256View::OnUpdateResLow(CCmdUI* pCmdUI) {
- pCmdUI->SetCheck(m_iResolution == 15);
- }
- void CED256View::OnUpdateResMedium(CCmdUI* pCmdUI) {
- pCmdUI->SetCheck(m_iResolution == 4);
- }
- void CED256View::OnUpdateResHigh(CCmdUI* pCmdUI) {
- pCmdUI->SetCheck(m_iResolution == 1);
- }