paint.cpp

来自「一个由Mike Gashler完成的机器学习方面的includes neural」· C++ 代码 · 共 1,283 行 · 第 1/3 页

CPP
1,283
字号
	{
		m_pCanvas->SetVertScroll(pScrollBar->GetPos());
		RedrawCanvas();
	}

	virtual void OnCanvasMouseDown(GWidgetCanvas* pCanvas, int nButton, int x, int y)
	{
		m_pCurrentTool->OnMouseDown(nButton, x, y);
		RedrawCanvas();
	}

	virtual void OnCanvasMouseUp(GWidgetCanvas* pCanvas, int nButton, int x, int y)
	{
		m_pCurrentTool->OnMouseUp(nButton, x, y);
		RedrawCanvas();
	}

	virtual void OnCanvasMouseMove(GWidgetCanvas* pCanvas, int x, int y, bool bPressed)
	{
		if(x < (int)m_pImage->GetWidth() && y < (int)m_pImage->GetHeight())
			m_pCurrentTool->OnMouseMove(x, y, bPressed);
		if(bPressed)
			RedrawCanvas();
	}

	void SetCurrentTool(PaintTool* pTool)
	{
		m_pCurrentTool = pTool;
	}

	void ZoomIn()
	{
		m_pCanvas->SetZoom(m_pCanvas->GetZoom() * 2);
		CleanCanvas();
	}

	void ZoomOut()
	{
		m_pCanvas->SetZoom(m_pCanvas->GetZoom() / 2);
		CleanCanvas();
	}
};


// ----------------------------------------------------------------------------

class TabDialog : public GWidgetDialog
{
protected:
	PaintController* m_pController;
	GWidgetImageButton* m_pButtonManual;

public:
	TabDialog(PaintController* pController, int w)
	 : GWidgetDialog(w, TOOL_AREA_SIZE, PAINT_AREA_BACKGROUND_COLOR)
	{
		m_pController = pController;

		// Make the manual button
		GImage* pManualImage = ControllerBase::GetManualImage();
		m_pButtonManual = new GWidgetImageButton(this, w - pManualImage->GetWidth() / 2 - 5, 5, pManualImage);
	}

	virtual ~TabDialog()
	{
	}

	virtual void OnReleaseImageButton(GWidgetImageButton* pButton)
	{
		if(pButton == m_pButtonManual)
			OpenAppFile("../doc/Waffles/Paint.html");
		else
			GAssert(false, "unrecognized image button");
	}
};

// ----------------------------------------------------------------------------

class TabOpen : public TabDialog
{
protected:
	GWidgetFileSystemBrowser* m_pFileSystemBrowser;

public:
	TabOpen(PaintController* pController, int w)
	 : TabDialog(pController, w)
	{
		m_pFileSystemBrowser = new GWidgetFileSystemBrowser(this, 0, 0, 500, TOOL_AREA_SIZE, ".png;.bmp;.pgm;.ppm");
	}

	virtual ~TabOpen()
	{
	}

	virtual void OnReleaseTextButton(GWidgetTextButton* pButton)
	{
	}

	virtual void OnSelectFilename(GWidgetFileSystemBrowser* pBrowser, const char* szFilename)
	{
		m_pController->OnOpenFile(szFilename);
	}
};


// ----------------------------------------------------------------------------

class TabSave : public TabDialog
{
protected:
	GWidgetFileSystemBrowser* m_pFileSystemBrowser;

public:
	TabSave(PaintController* pController, int w)
	 : TabDialog(pController, w)
	{
		m_pFileSystemBrowser = new GWidgetFileSystemBrowser(this, 0, 0, 500, TOOL_AREA_SIZE, ".png;.bmp;.pgm;.ppm");
	}

	virtual ~TabSave()
	{
	}

	virtual void OnReleaseTextButton(GWidgetTextButton* pButton)
	{
	}

	virtual void OnSelectFilename(GWidgetFileSystemBrowser* pBrowser, const char* szFilename)
	{
		m_pController->OnMaskFile(szFilename);
	}
};


// ----------------------------------------------------------------------------

class TabTools : public TabDialog
{
protected:
	GWidgetTextTab* m_pCurrentToolTab;
	GWidgetTextButton* m_pZoomInButton;
	GWidgetTextButton* m_pZoomOutButton;
	GWidgetTextButton* m_pHighPassButton;
	GWidgetTextButton* m_pMedianFilter;
	GWidgetTextButton* m_pThreshold;
	GWidgetTextButton* m_pDialateButton;
	GWidgetTextButton* m_pErodeButton;
	GWidgetTextButton* m_pOpenButton;
	GWidgetTextButton* m_pCloseButton;
	GWidgetTextButton* m_pThreshByRegion;
	GWidgetTextButton* m_pInvertButton;
	GWidgetTextButton* m_pEqualizeHistogram;
	GWidgetTextButton* m_pAutoSegment;
	GWidgetTextButton* m_pShowSelButton;
	GWidgetTextButton* m_pBlurButton;

	GWidgetTextTab* m_pTabPen;
	PaintToolPen* m_pToolPen;

	GWidgetTextTab* m_pTabStretch;
	PaintToolStretch* m_pToolStretch;

	GWidgetTextTab* m_pTabSmartSelect;
	PaintToolSmartSelect* m_pToolSmartSelect;

	GWidgetTextTab* m_pTabBezier;
	PaintToolBezier* m_pToolBezier;

	GWidgetTextTab* m_pTabBorder;
	PaintToolBorder* m_pToolBorder;

	GWidgetTextBox* m_pTB1;
	GWidgetTextBox* m_pTB2;

public:
	TabTools(PaintController* pController, int w)
	 : TabDialog(pController, w)
	{
		m_pZoomInButton = new GWidgetTextButton(this, 5, 30, 80, 20, "Zoom In");
		m_pZoomOutButton = new GWidgetTextButton(this, 5, 54, 80, 20, "Zoom Out");
		m_pHighPassButton = new GWidgetTextButton(this, 5, 78, 80, 20, "High Pass");
		m_pMedianFilter = new GWidgetTextButton(this, 5, 102, 80, 20, "Med. Filter");
		m_pThreshold = new GWidgetTextButton(this, 5, 126, 80, 20, "Auto Thresh");
		m_pDialateButton = new GWidgetTextButton(this, 90, 30, 80, 20, "Dialate");
		m_pErodeButton = new GWidgetTextButton(this, 90, 54, 80, 20, "Erode");
		m_pOpenButton = new GWidgetTextButton(this, 90, 78, 80, 20, "Morph Open");
		m_pCloseButton = new GWidgetTextButton(this, 90, 102, 80, 20, "Morph Close");
		m_pThreshByRegion = new GWidgetTextButton(this, 90, 126, 80, 20, "Rgn. Thresh");
		m_pInvertButton = new GWidgetTextButton(this, 175, 30, 80, 20, "Invert");
		m_pEqualizeHistogram = new GWidgetTextButton(this, 175, 54, 80, 20, "Eq. Hist");
		m_pAutoSegment = new GWidgetTextButton(this, 175, 78, 80, 20, "Auto Seg.");
		m_pShowSelButton = new GWidgetTextButton(this, 175, 102, 80, 20, "Show Sel.");
		m_pBlurButton = new GWidgetTextButton(this, 260, 30, 80, 20, "Blur");

		m_pTabPen = new GWidgetTextTab(this, 5, 5, 50, 20, "Pen");
		m_pToolPen = new PaintToolPen(pController->GetCanvas());
		m_pCurrentToolTab = m_pTabPen;
		m_pCurrentToolTab->SetSelected(true);

		m_pTabStretch = new GWidgetTextTab(this, 55, 5, 50, 20, "Stretch");
		m_pToolStretch = new PaintToolStretch(pController->GetCanvas());

		m_pTabSmartSelect = new GWidgetTextTab(this, 105, 5, 100, 20, "Smart Select");
		m_pToolSmartSelect = new PaintToolSmartSelect(pController->GetCanvas(), pController->GetSelectionMask());

		m_pTabBorder = new GWidgetTextTab(this, 205, 5, 50, 20, "Border");
		m_pToolBorder = new PaintToolBorder(pController->GetCanvas());

		m_pTabBezier = new GWidgetTextTab(this, 255, 5, 50, 20, "Bezier");
		m_pToolBezier = new PaintToolBezier(pController->GetCanvas());

		new GWidgetTextLabel(this, 500, 34, 150, 16, "Eq. Hist. Amount");
		m_pTB1 = new GWidgetTextBox(this, 500, 50, 50, 20);
		m_pTB1->SetText(".5");

		new GWidgetTextLabel(this, 500, 84, 150, 16, "Open Amount");
		m_pTB2 = new GWidgetTextBox(this, 500, 100, 50, 20);
		m_pTB2->SetText("2");
	}

	virtual ~TabTools()
	{
		delete(m_pToolPen);
		delete(m_pToolStretch);
		delete(m_pToolSmartSelect);
		delete(m_pToolBezier);
	}

	virtual void OnReleaseTextButton(GWidgetTextButton* pButton)
	{
		GImage* pImage = m_pController->GetCanvas();
		if(pButton == m_pZoomInButton)
			m_pController->ZoomIn();
		else if(pButton == m_pZoomOutButton)
			m_pController->ZoomOut();
		else if(pButton == m_pHighPassButton)
			pImage->HighPassFilter(.1);
		else if(pButton == m_pMedianFilter)
			pImage->MedianFilter((float)2);
		else if(pButton == m_pThreshold)
		{
			int nGrayscaleValue = pImage->ComputeOptimalGrayscaleThreshold();
			pImage->Threshold(nGrayscaleValue);
		}
		else if(pButton == m_pDialateButton)
		{
			GImage se;
			se.MakeGaussianKernel(3, (float)1);
			pImage->Dialate(&se);
		}
		else if(pButton == m_pErodeButton)
		{
			GImage se;
			se.MakeGaussianKernel(3, (float)1);
			pImage->Erode(&se);
		}
		else if(pButton == m_pOpenButton)
			pImage->Open(1);
		else if(pButton == m_pCloseButton)
			pImage->Open(-1);
		else if(pButton == m_pThreshByRegion)
		{
			//pImage->HighPassFilter(.1);
			pImage->ThresholdByRegion(1100, 5, true);
		}
		else if(pButton == m_pInvertButton)
			pImage->Invert();
		else if(pButton == m_pEqualizeHistogram)
		{
			char szTmp[64];
			m_pTB1->GetText()->GetAnsi(szTmp, 64);
			float fEqualizeAmount = (float)atof(szTmp);
			pImage->LocallyEqualizeColorSpread(MAX(pImage->GetWidth(), pImage->GetHeight()) * 2, fEqualizeAmount);
		}
		else if(pButton == m_pAutoSegment)
		{
			char szTmp[64];
			m_pTB1->GetText()->GetAnsi(szTmp, 64);
			float fEqualizeAmount = (float)atof(szTmp);
			pImage->LocallyEqualizeColorSpread(MAX(pImage->GetWidth(), pImage->GetHeight()) * 2, fEqualizeAmount);
			
			int nGrayscaleValue = pImage->ComputeOptimalGrayscaleThreshold();
			pImage->Threshold(nGrayscaleValue);
			
			m_pTB2->GetText()->GetAnsi(szTmp, 64);
			int nOpenAmount = atoi(szTmp);
			pImage->Open(nOpenAmount);
			pImage->ThresholdByRegion(1100, 5, false);

			GImage se;
			se.MakeGaussianKernel(3, (float)1);
			pImage->Erode(&se);
			
			pImage->Open(1);
		}
		else if(pButton == m_pShowSelButton)
		{
			GImage* pSelection = m_pController->GetSelectionMask();
			int x, y, c;
			for(y = 0; y < pImage->GetHeight(); y++)
			{
				for(x = 0; x < pImage->GetWidth(); x++)
				{
					c = gAlpha(pSelection->GetPixel(x, y));
					pImage->SetPixel(x, y, gARGB(0xff, c, c, c));
				}
			}
			pSelection->Clear(0);
			m_pController->CleanCanvas();
		}
		else if(pButton == m_pBlurButton)
		{
			pImage->Blur(7);
			//pImage->QuickBlur(5);
		}
		else
			GAssert(false, "unrecognized button");

		// Redraw the canvas
		m_pController->RedrawCanvas();
	}

	void SaveVector(double* pVector, const char* szFilename)
	{
		GImage image;
		image.SetSize(2 * OCR_HALF_VEC_SIZE, 2 * OCR_HALF_VEC_SIZE);
		image.Clear(0xffffffff);
		int x, y;
		for(x = 0; x < 2 * OCR_HALF_VEC_SIZE; x++)
		{
			for(y = 0; y < OCR_HALF_VEC_SIZE * pVector[x] && y < 2 * OCR_HALF_VEC_SIZE; y++)
				image.SetPixel(x, 2 * OCR_HALF_VEC_SIZE - 1 - y, x >= OCR_HALF_VEC_SIZE ? 0xff00ff00 : 0xff0000ff);
		}
		image.SaveBMPFile(szFilename);
	}

	double EvaluateOCRVector(double* pVector)
	{
		GAssert((OCR_HALF_VEC_SIZE & 1) == 0, "OCR_HALF_VEC_SIZE should be a multiple of 2");
		double a = 0;
		double b = 0;
		double c = 0;
		double d = 0;
		int i;
		for(i = 0; i < OCR_HALF_VEC_SIZE / 2; i++)
		{
			a += pVector[i];
			b += pVector[OCR_HALF_VEC_SIZE / 2 + i];
			c += pVector[OCR_HALF_VEC_SIZE + i];
			d += pVector[OCR_HALF_VEC_SIZE * 3 / 2 + i];
		}
		return 7.1 * (a + b) / (MAX(c + d, .00001)) + 2.5 * (a / MAX(b, .00001)) + (c / MAX(d, .00001));
	}

	void RotateOCRVector(double* pVector)
	{
		GTEMPBUF(double, pTemp, 2 * OCR_HALF_VEC_SIZE);
		memcpy(pTemp, pVector, sizeof(double) * 2 * OCR_HALF_VEC_SIZE);
		int i;
		for(i = 0; i < OCR_HALF_VEC_SIZE; i++)
		{
			pVector[i] = pTemp[OCR_HALF_VEC_SIZE + i];
			pVector[OCR_HALF_VEC_SIZE + i] = pTemp[OCR_HALF_VEC_SIZE - 1 - i];
		}
	}

	void MakeOCRVector(double* pOutVector, GImage* pImage, int nRegion)
	{
		// Find the bounds
		int l = pImage->GetWidth() - 1;
		int r = 0;
		int t = pImage->GetHeight() - 1;
		int b = 0;
		int x, y, n;
		for(y = 0; y < pImage->GetHeight(); y++)
		{
			for(x = 0; x < pImage->GetWidth(); x++)
			{
				if((int)pImage->GetPixel(x, y) == nRegion)
				{
					if(x < l)
						l = x;
					if(x > r)
						r = x;
					if(y < t)
						t = y;
					if(y > b)
						b = y;
				}
			}
		}

		// Compute the vector
		int i = 0;
		int j = 0;
		int w = r - l + 1;
		int h = b - t + 1;
		int min, max, nCount, nTot;
		for(n = 0; n < OCR_HALF_VEC_SIZE; n++)
		{
			// Vertical profile
			min = n * w / OCR_HALF_VEC_SIZE + l;
			max = (n + 1) * w / OCR_HALF_VEC_SIZE + l;
			if(max == min)
				max++;
			nCount = 0;
			nTot = 0;
			for(x = min; x < max; x++)
			{
				for(y = t; y <= b; y++)
				{
					if((int)pImage->GetPixel(x, y) == nRegion)
						nCount++;
					nTot++;
				}
			}
			GAssert(nCount > 0, "something's wrong");
			pOutVector[n] = (double)nCount /** h*/ / (nTot /** w*/);

			// Horizontal profile
			min = n * h / OCR_HALF_VEC_SIZE + t;
			max = (n + 1) * h / OCR_HALF_VEC_SIZE + t;
			if(max == min)
				max++;
			nCount = 0;
			nTot = 0;
			for(y = min; y < max; y++)
			{

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?