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

#include <vcl.h>
#pragma hdrstop

#include "AutoBrightnessSetting_Form.h"
#include "ColorCode_Form.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "TntStdCtrls"
#pragma link "TntExtCtrls"
#pragma link "TntButtons"
#pragma link "TntComCtrls"
#pragma resource "*.dfm"
TAutoBrightnessSettingForm *AutoBrightnessSettingForm;
//---------------------------------------------------------------------------
__fastcall TAutoBrightnessSettingForm::TAutoBrightnessSettingForm(TComponent* Owner)
	: TForm(Owner)
{
	if (DefaultLCID == 1028 || DefaultLCID == 2052 || DefaultLCID == 3076 || DefaultLCID == 4100)
		ComponentSetFontName(this, "SimSun");
	else if (DefaultLCID == 1041)
		ComponentSetFontName(this, "Meiryo UI");
  else if(DefaultLCID == 3082)
  {
    ComponentSetFontName(this, "Segoe UI");
    ComponentSetMultiLine(this);
  }

	helpString[PROCESSING_STEP_NONE] = AUTOBRIGHTNESSSETTING_FORM_TEXT_10;
	helpString[PROCESSING_STEP_GET_BACKGROUND_INFO] = AUTOBRIGHTNESSSETTING_FORM_TEXT_11;
	helpString[PROCESSING_STEP_GET_OBJECT_INFO] = AUTOBRIGHTNESSSETTING_FORM_TEXT_12 + AUTOBRIGHTNESSSETTING_FORM_TEXT_34;
	helpString[PROCESSING_STEP_SET_MAIN_CAMERA_BRIGHTNESS] = AUTOBRIGHTNESSSETTING_FORM_TEXT_13;
	helpString[PROCESSING_STEP_SET_SUB_CAMERA_BRIGHTNESS] = AUTOBRIGHTNESSSETTING_FORM_TEXT_14;
	helpString[PROCESSING_STEP_CHECK_CAMERA_BRIGHTNESS] = AUTOBRIGHTNESSSETTING_FORM_TEXT_15;

	TextMsgString[0] = AUTOBRIGHTNESSSETTING_FORM_TEXT_16;
	TextMsgString[1] = AUTOBRIGHTNESSSETTING_FORM_TEXT_17;
	TextMsgString[2] = AUTOBRIGHTNESSSETTING_FORM_TEXT_18;
	TextMsgString[3] = AUTOBRIGHTNESSSETTING_FORM_TEXT_19;
	TextMsgString[4] = AUTOBRIGHTNESSSETTING_FORM_TEXT_20;
	TextMsgString[5] = AUTOBRIGHTNESSSETTING_FORM_TEXT_21;
	TextMsgString[6] = AUTOBRIGHTNESSSETTING_FORM_TEXT_22;
	TextMsgString[7] = AUTOBRIGHTNESSSETTING_FORM_TEXT_23;
	TextMsgString[8] = AUTOBRIGHTNESSSETTING_FORM_TEXT_24;
	TextMsgString[9] = AUTOBRIGHTNESSSETTING_FORM_TEXT_25;
	TextMsgString[10] = AUTOBRIGHTNESSSETTING_FORM_TEXT_26;
	TextMsgString[11] = AUTOBRIGHTNESSSETTING_FORM_TEXT_27;
	TextMsgString[12] = AUTOBRIGHTNESSSETTING_FORM_TEXT_28;
	TextMsgString[13] = AUTOBRIGHTNESSSETTING_FORM_TEXT_29;
	TextMsgString[14] = AUTOBRIGHTNESSSETTING_FORM_TEXT_30;
	TextMsgString[15] = AUTOBRIGHTNESSSETTING_FORM_TEXT_31;

	StartButton->Caption = MACHINESETTINGTESTFORM_BUTTON_CAPTION_07;  // 시작 , Start
	StopButton->Caption = MACHINESETTINGTESTFORM_BUTTON_CAPTION_13;

	GroupBox3->Caption = AUTOBRIGHTNESSSETTING_FORM_TEXT_01;

	GroupBox1->Caption = AUTOBRIGHTNESSSETTING_FORM_TEXT_02;
	Label15->Caption = AUTOBRIGHTNESSSETTING_FORM_TEXT_02;

	GroupBox2->Caption = AUTOBRIGHTNESSSETTING_FORM_TEXT_03;
	Label16->Caption = AUTOBRIGHTNESSSETTING_FORM_TEXT_03;

	GroupBox5->Caption = AUTOBRIGHTNESSSETTING_FORM_TEXT_04;
	Label17->Caption = AUTOBRIGHTNESSSETTING_FORM_TEXT_05;
	Label18->Caption = AUTOBRIGHTNESSSETTING_FORM_TEXT_06;
	ApplyAverageValueCheckBox->Caption = AUTOBRIGHTNESSSETTING_FORM_TEXT_07;

	TntGroupBox1->Caption = AUTOBRIGHTNESSSETTING_FORM_TEXT_08;
	GroupBox4->Caption = AUTOBRIGHTNESSSETTING_FORM_TEXT_09;

    CloseButton->Caption = CALIBRATIONFORM_BUTTON_CAPTION_11;

    TntLabel1->Caption	= CALIBRATIONFORM_BUTTON_CAPTION_12;
    TntLabel2->Caption	= CALIBRATIONFORM_BUTTON_CAPTION_13;
    TntLabel3->Caption	= CALIBRATIONFORM_BUTTON_CAPTION_14;
}
//---------------------------------------------------------------------------
void __fastcall TAutoBrightnessSettingForm::SetActiveComponents(bool bActive)
{
	if (bActive)
	{
		StartButton->Enabled = true;
		StopButton->Enabled = true;
		CloseButton->Enabled = false;
		Down1->Enabled = false;
		Down2->Enabled = false;
		ApplyAverageValueCheckBox->Enabled = false;
		Up1->Enabled = false;
		Up2->Enabled = false;

		for (int cameraIndex = 1; cameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)              //++
		{
			TTntSpeedButton *cameraSpeedButton = (TTntSpeedButton *)FindComponent("CameraSpeedButton" + IntToStr(cameraIndex));

			if (cameraSpeedButton)
			{
				cameraSpeedButton->Enabled = false;
			}
		}
	}
	else
	{
		StartButton->Enabled = true;
		StopButton->Enabled = true;
		CloseButton->Enabled = true;
		Down1->Enabled = true;
		Down2->Enabled = true;
		ApplyAverageValueCheckBox->Enabled = true;
		Up1->Enabled = true;
		Up2->Enabled = true;

		for (int cameraIndex = 1; cameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
		{
			TTntSpeedButton *cameraSpeedButton = (TTntSpeedButton *)FindComponent("CameraSpeedButton" + IntToStr(cameraIndex));

			if (cameraSpeedButton)
			{
				cameraSpeedButton->Enabled = true;
			}
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TAutoBrightnessSettingForm::FormCreate(TObject *Sender)
{
	GroupBox1->DoubleBuffered = true;
	GroupBox2->DoubleBuffered = true;

	CameraGainForTabletRecognizationPanel->Caption = IntToStr(DEFAULT_OBJECT_TRACKING_GAIN);
	TabletDefaultBrighnessPanel->Caption = IntToStr(DEFAULT_TARGET_BRIGHTNESS_LEVEL);

	SetActiveComponents(false);
	InitResultComponent();

	ActiveVerticalCameraIndex = DEFAULT_VERTICAL_ACTIVE_CAMERA_INDEX;
	ActiveSideCameraIndex = DEFAULT_SIDE_ACTIVE_CAMERA_INDEX;

	RefeshAcitveCamera();

	processingStep = PROCESSING_STEP_NONE;

	helpStatus = 0;
	helpColor[0] = clWhite;
	helpColor[1] = 0x0053160D;

	lastRefreshTime = 0;
	helpTimer->Enabled = true;

	RefreshEnabledCamera();
	RefreshCameraBrightnessParams();

	globalStudySW = false;

	bExecutionBrightnessStudy = false;

	bGlobalStopSW = false;
  for(int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
  {
    AnsiString ConvertString;
    if(SystemLinkCameraInfo[globalCameraIndex] != 0 && CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D)
    {
      TTntLabel *CameraLabel = (TTntLabel *)FindComponent("CameraLabel" + IntToStr(globalCameraIndex+1));
      TTntPanel *CameraNamePanel = (TTntPanel *) FindComponent("CameraNamePanel" + IntToStr(globalCameraIndex+1));
      TTntSpeedButton *CameraSpeedButton = (TTntSpeedButton *)FindComponent("CameraSpeedButton" + IntToStr(globalCameraIndex+1));

      ConvertString = ConvertCameraIndex(globalCameraIndex);

      CameraLabel->Caption = ConvertString;
      CameraNamePanel->Caption = ConvertString;
      CameraSpeedButton->Caption = ConvertString;       
    }
  }

  if(GlobalProgramID == PROGRAM_ID_150P)
  {
    // SELMA150P
    int MoveD = ComponentReposition(1,0,0,CameraImage3->Width);
    int MoveD1 = ComponentReposition(4,0,0,CameraSpeedButton3->Width);
    int MoveD2 = ComponentReposition(3,CameraNamePanel2->Top, CameraNamePanel4->Top,0);
    for(int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
    {
      if(globalCameraIndex != SD1_3D_FRONT_FACE_CAMERA_INDEX-1 && globalCameraIndex != SD2_3D_FRONT_FACE_CAMERA_INDEX-1)
      {
        TTntImage *CameraImage = (TTntImage *)FindComponent("CameraImage" + IntToStr(globalCameraIndex+1));
        TTntLabel *CameraLabel = (TTntLabel *)FindComponent("CameraLabel" + IntToStr(globalCameraIndex+1));
        TTntLabel *CameraBrightnessValuePanel = (TTntLabel *)FindComponent("CameraBrightnessValuePanel" + IntToStr(globalCameraIndex+1));
        TProgressBar *ProgressBarCam = (TProgressBar *)FindComponent("ProgressBarCam" + IntToStr(globalCameraIndex+1));

        TTntSpeedButton *CameraSpeedButton = (TTntSpeedButton *)FindComponent("CameraSpeedButton" + IntToStr(globalCameraIndex+1));

        TTntPanel *CameraNamePanel = (TTntPanel *) FindComponent("CameraNamePanel" + IntToStr(globalCameraIndex+1));
        TTntPanel *CameraStatusPanel = (TTntPanel *) FindComponent("CameraStatusPanel" + IntToStr(globalCameraIndex+1));
        TTntPanel *CameraBrightnessLevelPanel = (TTntPanel *) FindComponent("CameraBrightnessLevelPanel" + IntToStr(globalCameraIndex+1));
        TTntPanel *CameraShutterSpeedPanel = (TTntPanel *) FindComponent("CameraShutterSpeedPanel" + IntToStr(globalCameraIndex+1));
        TTntPanel *CameraGainPanel = (TTntPanel *) FindComponent("CameraGainPanel" + IntToStr(globalCameraIndex+1));

        if(SystemLinkCameraInfo[globalCameraIndex] == 0)
        {
          CameraImage->Visible = false;
          CameraLabel->Visible = false;
          CameraBrightnessValuePanel->Visible = false;
          ProgressBarCam->Visible = false;

          CameraSpeedButton->Visible = false;

          CameraNamePanel->Visible = false;
          CameraStatusPanel->Visible = false;
          CameraBrightnessLevelPanel->Visible = false;
          CameraShutterSpeedPanel->Visible = false;
          CameraGainPanel->Visible = false;
        }
        else
        {
          CameraImage->Left += MoveD;
          CameraLabel->Left += MoveD;
          CameraBrightnessValuePanel->Left += MoveD;
          ProgressBarCam->Left += MoveD;

          if(globalCameraIndex+1 == 2 || globalCameraIndex+1 == 4 ||
          globalCameraIndex+1 == 10 || globalCameraIndex+1 == 12 )
          {
            CameraSpeedButton->Left += MoveD1;
          }

          if(globalCameraIndex+1 == 1 || globalCameraIndex+1 == 2 || globalCameraIndex+1 == 4 )
          {
            CameraNamePanel->Top += MoveD2;
            CameraStatusPanel->Top += MoveD2;
            CameraBrightnessLevelPanel->Top += MoveD2;
            CameraShutterSpeedPanel->Top += MoveD2;
            CameraGainPanel->Top += MoveD2;
          }
          else if(globalCameraIndex+1 == 9 || globalCameraIndex+1 == 10 || globalCameraIndex+1 == 12)
          {
            CameraNamePanel->Top -= MoveD2;
            CameraStatusPanel->Top -= MoveD2;
            CameraBrightnessLevelPanel->Top -= MoveD2;
            CameraShutterSpeedPanel->Top -= MoveD2;
            CameraGainPanel->Top -= MoveD2;
          }
          else if(globalCameraIndex+1 == 14 || globalCameraIndex+1 == 16)
          {
            CameraNamePanel->Top -= MoveD2*2;
            CameraStatusPanel->Top -= MoveD2*2;
            CameraBrightnessLevelPanel->Top -= MoveD2*2;
            CameraShutterSpeedPanel->Top -= MoveD2*2;
            CameraGainPanel->Top -= MoveD2*2;
          }

        }
      }
    }
    Label16->Left += MoveD1;
  }
  else if(ProductData.TabletType == TABLET_TYPE_SUGAR_COATED)
  {
    for(int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
    {
      if(globalCameraIndex == SD1_2D_SIDE_FACE_00_CAMERA_INDEX - 1 ||
          globalCameraIndex == SD1_2D_OTHER_SIDE_FACE_00_CAMERA_INDEX - 1 ||
          globalCameraIndex == SD2_2D_SIDE_FACE_00_CAMERA_INDEX - 1 ||
          globalCameraIndex == SD2_2D_OTHER_SIDE_FACE_00_CAMERA_INDEX - 1)
      {
        TTntImage *CameraImage = (TTntImage *)FindComponent("CameraImage" + IntToStr(globalCameraIndex+1));
        TTntLabel *CameraLabel = (TTntLabel *)FindComponent("CameraLabel" + IntToStr(globalCameraIndex+1));
        TTntLabel *CameraBrightnessValuePanel = (TTntLabel *)FindComponent("CameraBrightnessValuePanel" + IntToStr(globalCameraIndex+1));
        TProgressBar *ProgressBarCam = (TProgressBar *)FindComponent("ProgressBarCam" + IntToStr(globalCameraIndex+1));

        TTntSpeedButton *CameraSpeedButton = (TTntSpeedButton *)FindComponent("CameraSpeedButton" + IntToStr(globalCameraIndex+1));

        TTntPanel *CameraNamePanel = (TTntPanel *) FindComponent("CameraNamePanel" + IntToStr(globalCameraIndex+1));
        TTntPanel *CameraStatusPanel = (TTntPanel *) FindComponent("CameraStatusPanel" + IntToStr(globalCameraIndex+1));
        TTntPanel *CameraBrightnessLevelPanel = (TTntPanel *) FindComponent("CameraBrightnessLevelPanel" + IntToStr(globalCameraIndex+1));
        TTntPanel *CameraShutterSpeedPanel = (TTntPanel *) FindComponent("CameraShutterSpeedPanel" + IntToStr(globalCameraIndex+1));
        TTntPanel *CameraGainPanel = (TTntPanel *) FindComponent("CameraGainPanel" + IntToStr(globalCameraIndex+1));

        if(CameraImage)
        {
          CameraImage->Visible = false;
        }

        if(CameraLabel)
        {
          CameraLabel->Visible = false;
        }

        if(CameraBrightnessValuePanel)
        {
          CameraBrightnessValuePanel->Visible = false;
        }

        if(ProgressBarCam)
        {
          ProgressBarCam->Visible = false;
        }

        if(CameraSpeedButton)
        {
          CameraSpeedButton->Visible = false;
        }

        if(CameraNamePanel)
        {
          CameraNamePanel->Visible = false;
        }

        if(CameraStatusPanel)
        {
          CameraStatusPanel->Visible = false;
        }

        if(CameraBrightnessLevelPanel)
        {
          CameraBrightnessLevelPanel->Visible = false;
        }

        if(CameraShutterSpeedPanel)
        {
          CameraShutterSpeedPanel->Visible = false;
        }

        if(CameraGainPanel)
        {
          CameraGainPanel->Visible = false;
        }
      }
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TAutoBrightnessSettingForm::CloseButtonClick(
	TObject *Sender)
{
	if (bExecutionBrightnessStudy)
	{
		if (MessageDlgFA(TextMsgString[0], mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrOk)
		{
			bool bAllCameraStudied = true;
			for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
			{
				if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D)
				{
					if (brightnessStudyCompleted[globalCameraIndex] != CAMERA_BRIGHTNESS_CHECK_COMPLETED)
					{
						bAllCameraStudied = false;
						break;
					}
				}
			}

			bool finalSaveChecking;
			if (bAllCameraStudied == false)
			{
				finalSaveChecking = false;
				if (MessageDlgFA(TextMsgString[1], mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrOk)
				{
					finalSaveChecking = true;
				}
			}
			else
			{
				finalSaveChecking = true;
			}

			if (finalSaveChecking)
			{
				if (bAllCameraStudied)
				{
					int frontFaceAvgShutterSpeed;
					int frontFaceAvgDigitGain;
					int sideFaceAvgShutterSpeed;
					int sideFaceAvgDigitGain;
					int tempCount1, tempCount2;

					frontFaceAvgShutterSpeed = frontFaceAvgDigitGain = tempCount1 = 0;
					sideFaceAvgShutterSpeed = sideFaceAvgDigitGain = tempCount2 = 0;
					for (int cameraIndex = 1; cameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
					{
						if (brightnessStudyCompleted[cameraIndex - 1] == CAMERA_BRIGHTNESS_CHECK_COMPLETED)
						{
							if (cameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX || cameraIndex == SD2_2D_FRONT_FACE_CAMERA_INDEX)
							{
								frontFaceAvgShutterSpeed += StudyShutterSpeed[cameraIndex - 1];
								frontFaceAvgDigitGain += StudyDigitalGain[cameraIndex - 1];
								tempCount1++;
							}
							else
							{
								sideFaceAvgShutterSpeed += StudyShutterSpeed[cameraIndex - 1];
								sideFaceAvgDigitGain += StudyDigitalGain[cameraIndex - 1];
								tempCount2++;
							}
						}
					}

					if (tempCount1)
					{
						frontFaceAvgShutterSpeed /= tempCount1;
						frontFaceAvgDigitGain /= tempCount1;
					}

					if (tempCount2)
					{
						sideFaceAvgShutterSpeed /= tempCount2;
						sideFaceAvgDigitGain /= tempCount2;
					}

					// 색상별 ShutterSpeed Table에는 설정에 관계없이 학습결과의 평균값을 적용
					int tempStudyShutterSpeed[SYSTEM_TOTAL_CAMERA_COUNT];
					int tempStudyDigitalGain[SYSTEM_TOTAL_CAMERA_COUNT];

					memset(tempStudyShutterSpeed, 0, sizeof(int) * SYSTEM_TOTAL_CAMERA_COUNT);
					memset(tempStudyDigitalGain, 0, sizeof(int) * SYSTEM_TOTAL_CAMERA_COUNT);

					for (int cameraIndex = 1; cameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
					{
						if (brightnessStudyCompleted[cameraIndex - 1] == CAMERA_BRIGHTNESS_CHECK_COMPLETED)
						{
							if (cameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX || cameraIndex == SD2_2D_FRONT_FACE_CAMERA_INDEX)
							{
								tempStudyShutterSpeed[cameraIndex - 1] = frontFaceAvgShutterSpeed;
								tempStudyDigitalGain[cameraIndex - 1] = frontFaceAvgDigitGain;
							}
							else
							{
								tempStudyShutterSpeed[cameraIndex - 1] = sideFaceAvgShutterSpeed;
								tempStudyDigitalGain[cameraIndex - 1] = sideFaceAvgDigitGain;
							}
						}
					}

					if (ApplyAverageValueCheckBox->Checked)
					{
						for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
						{
							if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D)
							{
								ProductData.ShutterSpeed[globalCameraIndex] = tempStudyShutterSpeed[globalCameraIndex];
								ProductData.DigitalGainV[globalCameraIndex] = tempStudyDigitalGain[globalCameraIndex];
							}
						}
					}
					else
					{
						for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
						{
							if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D)
							{
								ProductData.ShutterSpeed[globalCameraIndex] = StudyShutterSpeed[globalCameraIndex];
								ProductData.DigitalGainV[globalCameraIndex] = StudyDigitalGain[globalCameraIndex];
							}
						}
					}

					int SaveMask = 0;
					AnsiString fileName = GetProductDataFileName(ProductData.ProductCode);
					if (WriteProductData(fileName, ProductData))
					{
						SaveMask |= 0x0001;
					}

					// save shutter speed info
					AnsiString colorCodeName = ProductData.TabletColorCode;
					AnsiString shutterSpeedFileName = ProgramPath.Env + "\\ShutterSpeedInfor.ini";
					TColor CaptureTabletColor = GetColorByCode(colorCodeName);

					unsigned int twoDCameraMap = 0;
					for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
					{
						if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D)
						{
							twoDCameraMap |= (0x0001 << globalCameraIndex);
						}
					}

					if (SaveShutterSpeedInfo(shutterSpeedFileName, colorCodeName, CaptureTabletColor, tempStudyShutterSpeed, twoDCameraMap, tempStudyDigitalGain))
					{
						SaveMask |= 0x0010;
					}

					if (SaveMask == 0x0011)
					{
						MessageDlgFA(TextMsgString[2], mtConfirmation, TMsgDlgButtons() << mbOK);
					}
					else if (SaveMask == 0x0001)
					{
						MessageDlgFA(TextMsgString[3], mtConfirmation, TMsgDlgButtons() << mbOK);
					}
					else if (SaveMask == 0x0010)
					{
						MessageDlgFA(TextMsgString[4], mtConfirmation, TMsgDlgButtons() << mbOK);
					}
					else
					{
						MessageDlgFA(TextMsgString[5], mtConfirmation, TMsgDlgButtons() << mbOK);
					}
				}
				else
				{
					bool bVerticalStudy = false;
					bool bSideStudy = false;
					int tempVerticalCameraIndex = -1;
					int tempSideCameraIndex = -1;

					for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
					{
						if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D)
						{
							if (brightnessStudyCompleted[globalCameraIndex] == CAMERA_BRIGHTNESS_CHECK_COMPLETED)
							{
								if (globalCameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1 || globalCameraIndex == SD2_2D_FRONT_FACE_CAMERA_INDEX - 1)
								{
									bVerticalStudy = true;
									tempVerticalCameraIndex = globalCameraIndex;
								}
								else
								{
									bSideStudy = true;
									tempSideCameraIndex = globalCameraIndex;
								}
							}
						}
					}

					if (bVerticalStudy && bSideStudy)
					{
						for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
						{
							if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D)
							{
								if (globalCameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1 || globalCameraIndex == SD2_2D_FRONT_FACE_CAMERA_INDEX - 1)
								{
									ProductData.ShutterSpeed[globalCameraIndex] = StudyShutterSpeed[tempVerticalCameraIndex];
									ProductData.DigitalGainV[globalCameraIndex] = StudyDigitalGain[tempVerticalCameraIndex];
								}
								else
								{
									ProductData.ShutterSpeed[globalCameraIndex] = StudyShutterSpeed[tempSideCameraIndex];
									ProductData.DigitalGainV[globalCameraIndex] = StudyDigitalGain[tempSideCameraIndex];
								}
							}
						}

						int SaveMask = 0;
						AnsiString fileName = GetProductDataFileName(ProductData.ProductCode);
						if (WriteProductData(fileName, ProductData))
						{
							SaveMask |= 0x0001;
						}

						// save shutter speed info
						AnsiString colorCodeName = ProductData.TabletColorCode;
						AnsiString shutterSpeedFileName = ProgramPath.Env + "\\ShutterSpeedInfor.ini";
						TColor CaptureTabletColor = GetColorByCode(colorCodeName);

						unsigned int twoDCameraMap = 0;
						for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
						{
							if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D)
							{
								twoDCameraMap |= (0x0001 << globalCameraIndex);
							}
						}

						if (SaveShutterSpeedInfo(shutterSpeedFileName, colorCodeName, CaptureTabletColor, ProductData.ShutterSpeed, twoDCameraMap, ProductData.DigitalGainV))
						{
							SaveMask |= 0x0010;
						}

						if (SaveMask == 0x0011)
						{
							MessageDlgFA(TextMsgString[2], mtConfirmation, TMsgDlgButtons() << mbOK);
						}
						else if (SaveMask == 0x0001)
						{
							MessageDlgFA(TextMsgString[3], mtConfirmation, TMsgDlgButtons() << mbOK);
						}
						else if (SaveMask == 0x0010)
						{
							MessageDlgFA(TextMsgString[4], mtConfirmation, TMsgDlgButtons() << mbOK);
						}
						else
						{
							MessageDlgFA(TextMsgString[5], mtConfirmation, TMsgDlgButtons() << mbOK);
						}
					}
					else
					{
						MessageDlgFA(TextMsgString[6], mtConfirmation, TMsgDlgButtons() << mbOK);
						return;
					}
				}
			}
			else
			{
				MessageDlgFA(TextMsgString[7], mtConfirmation, TMsgDlgButtons() << mbOK);
				return;
			}
		}
		else
		{
			MessageDlgFA(TextMsgString[8], mtConfirmation, TMsgDlgButtons() << mbOK);
		}
	}

	this->Close();
}
//---------------------------------------------------------------------------

void __fastcall TAutoBrightnessSettingForm::InitResultComponent()
{
	for (int cameraIndex = 1; cameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
	{
		TTntPanel *CameraStatusPanel = (TTntPanel *)FindComponent("CameraStatusPanel" + IntToStr(cameraIndex));

		if (CameraStatusPanel)
		{
			CameraStatusPanel->Caption = "X";
		}
	}

	for (int cameraIndex = 1; cameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
	{
		TTntPanel *CameraBrightnessLevelPanel = (TTntPanel *)FindComponent("CameraBrightnessLevelPanel" + IntToStr(cameraIndex));

		if (CameraBrightnessLevelPanel)
		{
			CameraBrightnessLevelPanel->Caption = "N/A";
		}
	}

	for (int cameraIndex = 1; cameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
	{
		TTntPanel *CameraShutterSpeedPanel = (TTntPanel *)FindComponent("CameraShutterSpeedPanel" + IntToStr(cameraIndex));

		if (CameraShutterSpeedPanel)
		{
			CameraShutterSpeedPanel->Caption = "N/A";
		}
	}

	for (int cameraIndex = 1; cameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
	{
		TTntPanel *CameraGainPanel = (TTntPanel *)FindComponent("CameraGainPanel" + IntToStr(cameraIndex));

		if (CameraGainPanel)
		{
			CameraGainPanel->Caption = "N/A";
		}
	}

	for (int cameraIndex = 1; cameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
	{
		TTntPanel *CameraBrightnessValuePanel = (TTntPanel *)FindComponent("CameraBrightnessValuePanel" + IntToStr(cameraIndex));

		if (CameraBrightnessValuePanel)
		{
			CameraBrightnessValuePanel->Caption = "N/A";

		}
	}

	for (int cameraIndex = 1; cameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
	{
		TProgressBar *tempProgressBar = (TProgressBar *)FindComponent("ProgressBarCam" + IntToStr(cameraIndex));

		if (tempProgressBar)
		{
			tempProgressBar->Position = 0;
		}
	}

	for (int cameraIndex = 1; cameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
	{
		TTntImage *CameraImage = (TTntImage *)FindComponent("CameraImage" + IntToStr(cameraIndex));

		if (CameraImage)
		{
			CameraImage->Picture->Bitmap->Width = SYSTEM_CAMERA_WIDTH;
			CameraImage->Picture->Bitmap->Height = MAX_IMAGE_HEIGHT;
			CameraImage->Picture->Bitmap->PixelFormat = pf24bit;

			CameraImage->Canvas->Brush->Color = clBlack;
			CameraImage->Canvas->Brush->Style = bsSolid;
			CameraImage->Canvas->FillRect(Rect(0, 0, CameraImage->Picture->Bitmap->Width, CameraImage->Picture->Bitmap->Height));
		}
	}
}

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

void __fastcall TAutoBrightnessSettingForm::RefeshAcitveCamera()
{
	for (int cameraIndex = 1; cameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
	{
		TTntSpeedButton *cameraSpeedButton = (TTntSpeedButton *)FindComponent("CameraSpeedButton" + IntToStr(cameraIndex));

		if (cameraSpeedButton)
		{
			if (cameraIndex == ActiveVerticalCameraIndex ||
				cameraIndex == ActiveSideCameraIndex)
			{
				cameraSpeedButton->Font->Color = clRed;
			}
			else
			{
				cameraSpeedButton->Font->Color = clBlack;
			}
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TAutoBrightnessSettingForm::CameraSpeedButton1Click(
	TObject *Sender)
{
	TTntSpeedButton *cameraSpeedButton = (TTntSpeedButton *)Sender;
	ActiveVerticalCameraIndex = cameraSpeedButton->Tag;
	RefeshAcitveCamera();
}
//---------------------------------------------------------------------------

void __fastcall TAutoBrightnessSettingForm::CameraSpeedButton2Click(
	TObject *Sender)
{
	TTntSpeedButton *cameraSpeedButton = (TTntSpeedButton *)Sender;
	ActiveSideCameraIndex = cameraSpeedButton->Tag;
	RefeshAcitveCamera();
}
//---------------------------------------------------------------------------

void __fastcall TAutoBrightnessSettingForm::Up1Click(TObject *Sender)
{
	int currentValue = StrToInt(CameraGainForTabletRecognizationPanel->Caption);

	currentValue = min(MAX_DIGITAL_GAIN, currentValue + CAMERA_GAIN_SHIFT_SIZE);

	CameraGainForTabletRecognizationPanel->Caption = IntToStr(currentValue);
}
//---------------------------------------------------------------------------

void __fastcall TAutoBrightnessSettingForm::Down1Click(TObject *Sender)
{
	int currentValue = StrToInt(CameraGainForTabletRecognizationPanel->Caption);

	currentValue = max(MIN_DIGITAL_GAIN, currentValue - CAMERA_GAIN_SHIFT_SIZE);

	CameraGainForTabletRecognizationPanel->Caption = IntToStr(currentValue);
}
//---------------------------------------------------------------------------

void __fastcall TAutoBrightnessSettingForm::Up2Click(TObject *Sender)
{
	int currentValue = StrToInt(TabletDefaultBrighnessPanel->Caption);

	currentValue = min(MAX_BRIGHTNESS_LEVEL, currentValue + BRIGHTNESS_SHIFT_SIZE);

	TabletDefaultBrighnessPanel->Caption = IntToStr(currentValue);
}
//---------------------------------------------------------------------------

void __fastcall TAutoBrightnessSettingForm::Down2Click(TObject *Sender)
{
	int currentValue = StrToInt(TabletDefaultBrighnessPanel->Caption);

	currentValue = max(MIN_BRIGHTNESS_LEVEL, currentValue - BRIGHTNESS_SHIFT_SIZE);

	TabletDefaultBrighnessPanel->Caption = IntToStr(currentValue);
}
//---------------------------------------------------------------------------

void __fastcall TAutoBrightnessSettingForm::StartButtonClick(
	TObject *Sender)
{
	MachineControlPanel->Caption = AUTOBRIGHTNESSSETTING_FORM_TEXT_33;
	bGlobalStopSW = false;

	if (processingStep == PROCESSING_STEP_NONE)
	{
		InitImageBuffer();

		bool bIPBConnection = true;
		int IPBConnectionFailedCount = 0;
		int IPBConnectionTryCount = 0;
		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
			if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_DISCONNECT &&
				CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D && SystemLinkCameraInfo[globalCameraIndex] != 0)
			{
				int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;

				IPBConnectionTryCount++;
				if (!Comm_IsConnected(COMM_SPB + spbIndex))
				{
					bIPBConnection = false;
					IPBConnectionFailedCount++;
				}
			}
		}

		if (bIPBConnection == false)
		{
			if (IPBConnectionTryCount == IPBConnectionFailedCount)
			{
				MessageDlgFA(TextMsgString[9], mtConfirmation, TMsgDlgButtons() << mbOK);
				return;
			}
			else
			{
				if (MessageDlgFA(TextMsgString[10], mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) != mrOk)
				{
					MessageDlgFA(TextMsgString[9], mtConfirmation, TMsgDlgButtons() << mbOK);
					return;
				}
			}
		}

		Machine.MachineCleaning();

		StartButton->Enabled = false;
		CloseButton->Enabled = false;

		MachineControlPanel->Visible = true;
		while (1)
		{
			Machine.ReadPortStatus();

			Application->ProcessMessages();

			if (Machine.Status.OperationState == MACHINE_STATE_STOP ||
				Machine.Status.OperationState == MACHINE_STATE_CLEANING)
			{
				break;
			}
			else if (SimulationCheckBox->Checked)
			{
				break;
			}

			if (bGlobalStopSW)
			{
				StartButton->Enabled = true;
				CloseButton->Enabled = true;

				MachineControlPanel->Visible = false;

				return;
			}
		}

		StartButton->Enabled = true;
		CloseButton->Enabled = true;

		//MachineControlPanel->Visible = false;

		// 초기 상태
		bExecutionBrightnessStudy = false;
		globalStudySW = false;

		SetActiveComponents(true);
		InitResultComponent();

		StartButton->Caption = AUTOBRIGHTNESSSETTING_FORM_TEXT_32;

		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
      //++
			  MinBrightnessLevel[globalCameraIndex] = 256;
			  CameraBrightness[globalCameraIndex] = 0;
			  StudyShutterSpeed[globalCameraIndex] = 0;
			  StudyDigitalGain[globalCameraIndex] = 0;
			  brightnessStudyCompleted[globalCameraIndex] = CAMERA_BRIGHTNESS_CHECK_NONE;
			  continuousBrightnessOverCount[globalCameraIndex] = 0;
        checkedSW[globalCameraIndex] = false;

		}
	}

	processingStep++;

	if (processingStep > PROCESSING_STEP_NONE && processingStep != PROCESSING_STEP_COMPLETE)
	{
		CaptureStop();
		ImageLoadTimer->Enabled = false;

		Sleep(100);

		MachineControl();

		RefreshEnabledCamera();
		RefreshCameraBrightnessParams();

		if (SendSPBCaptureSetup())
		{
			TCaptureCommandParam_HCB captureCommandParam_HCB;
			captureCommandParam_HCB.Action = 1;
			captureCommandParam_HCB.FrameTime = StrToFloat(FrameTimeEdit->Text) * 20 + 0.5;
			captureCommandParam_HCB.LEDMask[0] = 0x00FFFFFF;
			captureCommandParam_HCB.LEDOnTime[0] = StrToFloat(LedOnTimeEdit->Text) * 20 + 0.5;
			captureCommandParam_HCB.ShutterDelay = StrToFloat(ShutterDelayEdit->Text) * 20 + 0.5;
			if (Comm_Request(COMM_HCB, CMD_TABLET_CAPTURE, &captureCommandParam_HCB, sizeof(TCaptureCommandParam_HCB),
				NULL, 0))
			{
				for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
				{
					cameraActiveCheckTime[globalCameraIndex] = Now().Val;           // ++
				}

				ImageLoadTimer->Enabled = true;
			}
		}
		else
		{
			MessageDlgFA(TextMsgString[11], mtConfirmation, TMsgDlgButtons() << mbOK);

			CaptureStop();
			ImageLoadTimer->Enabled = false;

			processingStep = PROCESSING_STEP_NONE;
			MachineControl();
			InitResultComponent();

			SetActiveComponents(false);
			StartButton->Caption = MACHINESETTINGTESTFORM_BUTTON_CAPTION_07;
		}
	}
	else if (processingStep == PROCESSING_STEP_COMPLETE)
	{
		CaptureStop();
		ImageLoadTimer->Enabled = false;

		processingStep = PROCESSING_STEP_NONE;
		MachineControl();
		InitResultComponent();

		// result table set
		SetBrightnessCheckingResult();

		// message
		MessageDlgFA(TextMsgString[12], mtConfirmation, TMsgDlgButtons() << mbOK);

		bExecutionBrightnessStudy = true;

		SetActiveComponents(false);
		StartButton->Caption = MACHINESETTINGTESTFORM_BUTTON_CAPTION_07;
	}
}
//---------------------------------------------------------------------------

void __fastcall TAutoBrightnessSettingForm::StopButtonClick(
	TObject *Sender)
{
	MachineControlPanel->Caption = WAITINGFORM_MSG_02;

	CaptureStop();
	ImageLoadTimer->Enabled = false;

	processingStep = PROCESSING_STEP_NONE;
	MachineControl();
	InitResultComponent();

	SetActiveComponents(false);
	StartButton->Caption = MACHINESETTINGTESTFORM_BUTTON_CAPTION_07;

	bGlobalStopSW = true;
}
//---------------------------------------------------------------------------


void __fastcall TAutoBrightnessSettingForm::helpTimerTimer(TObject *Sender)
{
	double currentTime = Now().Val;

	if ((currentTime - lastRefreshTime) * 24 * 3600 > HELP_REFRESH_TIME)
	{
		lastRefreshTime = currentTime;

		if (helpStatus == 0)
		{
			helpStatus = 1;
		}
		else
		{
			helpStatus = 0;
		}

		HelpLabel->Font->Color = helpColor[helpStatus];
	}

	HelpLabel->Caption = helpString[processingStep];
}
//---------------------------------------------------------------------------

void __fastcall TAutoBrightnessSettingForm::FrameTimeEditClick(
	TObject *Sender)
{
	TTntEdit *theEdit = (TTntEdit *)Sender;
	KeyboardForm->Text = theEdit->Text;
	if (KeyboardForm->ShowKeypad() == mrOk)
	{
		theEdit->Text = KeyboardForm->Text;
	}
}
//---------------------------------------------------------------------------

bool __fastcall TAutoBrightnessSettingForm::SendSPBCaptureSetup(void)
{
	bool returnValue = true;

	TCaptureSetupData captureSetupData;

	captureSetupData.CaptureType = CAPTURE_TYPE_SINGLE_CAPTURE;
	captureSetupData.CaptureMode = CAPTURE_MODE_DEFAULT;
	captureSetupData.FrameBufferCount = 3;

	for (int spbIndex = 0; spbIndex < SYSTEM_SPB_MAX_COUNT; spbIndex++)
	{
		if (Comm_IsConnected(COMM_SPB + spbIndex))
		{
			captureSetupData.CameraMask = 0;
			memset(captureSetupData.ShutterSpeed, 0, sizeof(unsigned short) * SYSTEM_SPB_CAMERA_MAX_COUNT);
			memset(captureSetupData.SubsamplingMode, 0, sizeof(unsigned char) * SYSTEM_SPB_CAMERA_MAX_COUNT);
			memset(captureSetupData.ShutterDelay, 0, sizeof(unsigned short) * SYSTEM_SPB_CAMERA_MAX_COUNT);
			memset(captureSetupData.TriggerFreq, 0, sizeof(unsigned short) * SYSTEM_SPB_CAMERA_MAX_COUNT);

			for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
			{
				if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_DISCONNECT &&
					CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D && SystemLinkCameraInfo[globalCameraIndex] != 0)
				{
					if (spbIndex == CameraMapInfo[globalCameraIndex].SPBIndex)
					{
						if (ImageCaptureActiveCamera[globalCameraIndex])
						{
							RefreshCameraInfo(globalCameraIndex);

							int camIndex = CameraMapInfo[globalCameraIndex].CamIndex;
							captureSetupData.CameraMask |= (0x0001 << camIndex);
							captureSetupData.ShutterSpeed[camIndex] = ShutterSpeedList[globalCameraIndex];
							captureSetupData.SubsamplingMode[camIndex] = RESOLUTION_NORMAL_QUALITY;
							captureSetupData.ShutterDelay[camIndex] = 0;
						}
					}
				}
			}
			captureSetupData.TabletType = ProductData.TabletType;
			captureSetupData.SensorLength= ProductData.StudiedSensor1Length;
			captureSetupData.ContainParams = 1;
			if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_SETUP, &captureSetupData, sizeof(TCaptureSetupData), NULL, 0))
			{
				returnValue = false;
			}
		}
	}

	return returnValue;
}

//---------------------------------------------------------------------------
void __fastcall TAutoBrightnessSettingForm::RefreshCameraInfo(int cameraIndex)
{
	// 사용자가 설정한 ShutterSpeed, Threshold, ROI(는 사실 Default) 를 반영
	int ShutterSpeed = 0;
	int Threshold = 0;
	int WriteMask = 0;
	int cameraGain = 1;

	if (processingStep == PROCESSING_STEP_SET_MAIN_CAMERA_BRIGHTNESS || processingStep == PROCESSING_STEP_SET_SUB_CAMERA_BRIGHTNESS)
	{
		ShutterSpeed = currentShutterSpeed[cameraIndex];
		cameraGain = currentDigitalGain[cameraIndex];
	}
	else
	{
		ShutterSpeed = ShutterSpeedList[cameraIndex];
		cameraGain = DigitalGainList[cameraIndex];
	}

	if (CameraMapInfo[cameraIndex].CameraInspectPosition == CAMERA_POSITION_3D)
		WriteMask |= CAMERA_WRITE_MASK_3D_SH;
	else
		WriteMask |= CAMERA_WRITE_MASK_2D_SH;

	if (CameraMapInfo[cameraIndex].CameraInspectPosition == CAMERA_POSITION_3D)
	{
		Threshold = ProductData.ThresholdFor3D[cameraIndex];
		WriteMask |= CAMERA_WRITE_MASK_TH;
	}

	TROIInfo DefaultROIInfo, ApplyROIInfo;
	AnsiString filePath;
	filePath = ProgramPath.Env + "\\NFACameraInformation.ini";
	DefaultROIInfo = ReadCameraInformation(filePath, cameraIndex);

	// Calibration 화면에서는 Default 값으로 ROI를 설정한다.
	memcpy(&ApplyROIInfo, &DefaultROIInfo, sizeof(TROIInfo));

	if (CameraMapInfo[cameraIndex].CameraInspectPosition != CAMERA_POSITION_3D)
	{
		WriteMask |= CAMERA_WRITE_MASK_2D_ROI;
	}
	else
	{
		WriteMask |= CAMERA_WRITE_MASK_3D_ROI;
	}

	if (CameraMapInfo[cameraIndex].CameraInspectPosition != CAMERA_POSITION_3D)
	{
		WriteMask |= CAMERA_WRITE_MASK_2D_SUBSAMPLING_MODE;
	}

	SetCameraInformation(ApplyROIInfo, ShutterSpeed, Threshold, 0, cameraIndex, WriteMask);
	SetCameraGain(cameraIndex + 1, SYSTEM_DEFAULT_ANLOG_GAIN, cameraGain, 0);
}
//---------------------------------------------------------------------------

void __fastcall TAutoBrightnessSettingForm::RefreshCameraBrightnessParams()
{
	if (processingStep == PROCESSING_STEP_NONE)
	{
		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
			ShutterSpeedList[globalCameraIndex] = DEFAULT_OBJECT_TRACKING_ST;
			DigitalGainList[globalCameraIndex] = DEFAULT_OBJECT_TRACKING_GAIN;
		}
	}
	else if (processingStep == PROCESSING_STEP_GET_BACKGROUND_INFO || processingStep == PROCESSING_STEP_GET_OBJECT_INFO)
	{
		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
			ShutterSpeedList[globalCameraIndex] = DEFAULT_OBJECT_TRACKING_ST;
			DigitalGainList[globalCameraIndex] = StrToInt(CameraGainForTabletRecognizationPanel->Caption);
		}
	}
	else if (processingStep == PROCESSING_STEP_SET_MAIN_CAMERA_BRIGHTNESS)
	{
		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
			fstStep[globalCameraIndex] = true;

			currentShutterSpeed[globalCameraIndex] = MAIN_MIN_SHUTTER_SPEED;
			currentDigitalGain[globalCameraIndex] = MIN_DIGITAL_GAIN;

			ShutterSpeedList[globalCameraIndex] = currentShutterSpeed[globalCameraIndex];
			DigitalGainList[globalCameraIndex] = currentDigitalGain[globalCameraIndex];
		}
	}
	else if (processingStep == PROCESSING_STEP_SET_SUB_CAMERA_BRIGHTNESS)
	{
		int mainCameraIndex;
		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
			if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_DISCONNECT &&
				CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D && SystemLinkCameraInfo[globalCameraIndex] != 0)
			{
				if (globalCameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1 || globalCameraIndex == SD2_2D_FRONT_FACE_CAMERA_INDEX - 1)
				{
					mainCameraIndex = ActiveVerticalCameraIndex - 1;
				}
				else
				{
					mainCameraIndex = ActiveSideCameraIndex - 1;
				}

				currentShutterSpeed[globalCameraIndex] = SUB_MIN_SHUTTER_SPEED;
				currentDigitalGain[globalCameraIndex] = StudyDigitalGain[mainCameraIndex];

				ShutterSpeedList[globalCameraIndex] = currentShutterSpeed[globalCameraIndex];
				DigitalGainList[globalCameraIndex] = currentDigitalGain[globalCameraIndex];
			}
		}
	}
	else
	{
		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
			if (brightnessStudyCompleted[globalCameraIndex])
			{
				currentShutterSpeed[globalCameraIndex] = StudyShutterSpeed[globalCameraIndex];
				currentDigitalGain[globalCameraIndex] = StudyDigitalGain[globalCameraIndex];
			}
			else
			{
				StudyShutterSpeed[globalCameraIndex] = MAIN_MIN_SHUTTER_SPEED;
				StudyDigitalGain[globalCameraIndex] = MIN_DIGITAL_GAIN;

				currentShutterSpeed[globalCameraIndex] = StudyShutterSpeed[globalCameraIndex];
				currentDigitalGain[globalCameraIndex] = StudyDigitalGain[globalCameraIndex];
			}

			ShutterSpeedList[globalCameraIndex] = currentShutterSpeed[globalCameraIndex];
			DigitalGainList[globalCameraIndex] = currentDigitalGain[globalCameraIndex];
		}
	}
}

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

void __fastcall TAutoBrightnessSettingForm::CaptureStop()
{
	TCaptureCommandParam_HCB captureCommandParam_HCB;
	captureCommandParam_HCB.Action = 0;

	for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	{
    //++
    if(SystemLinkCameraInfo[globalCameraIndex] != 0)
    {
		  int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;
		  int camIndex = CameraMapInfo[globalCameraIndex].CamIndex;

		  if (Comm_IsConnected(COMM_SPB + spbIndex))
		  {
		  	Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_STOP, &camIndex, sizeof(int));
	  	}
    }
	}

	if (Comm_Request(COMM_HCB, CMD_TABLET_CAPTURE, &captureCommandParam_HCB, sizeof(TCaptureCommandParam_HCB),
		NULL, 0))
	{
	}
}
//---------------------------------------------------------------------------
void __fastcall TAutoBrightnessSettingForm::ImageLoadTimerTimer(
	TObject *Sender)
{
	bool timerEnabled = ImageLoadTimer->Enabled;
	ImageLoadTimer->Enabled = false;
	bool bCaptureExist;
	unsigned int data[2];
	unsigned int receivedData[2];

	RefreshInactiveCameraComponent();

	for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	{
		if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_DISCONNECT &&
			CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D && SystemLinkCameraInfo[globalCameraIndex] != 0)
		{
			if (ImageCaptureActiveCamera[globalCameraIndex])
			{
				int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;
				int camIndex = CameraMapInfo[globalCameraIndex].CamIndex;
				data[0] = camIndex;

				try
				{
          if (processingStep == PROCESSING_STEP_SET_MAIN_CAMERA_BRIGHTNESS || processingStep == PROCESSING_STEP_SET_SUB_CAMERA_BRIGHTNESS)
          {
            if(checkedSW[globalCameraIndex]) continue;
          }

					if (Comm_IsConnected(COMM_SPB + spbIndex))
					{
						if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_EXIST, data, sizeof(unsigned int),
							receivedData, sizeof(unsigned int) * 2))
						{

						}

						if (receivedData[0])
						{
							bCaptureExist = true;
						}
						else
						{
							bCaptureExist = false;
						}

						if (bCaptureExist)
						{
							data[1] = MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT;
							if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_UPLOAD, data, 2 * sizeof(unsigned int),
								CaptureData, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT))
							{

							}

							cameraActiveCheckTime[globalCameraIndex] = Now().Val;

							TTntImage *DestImage;
							DestImage = (TTntImage *)FindComponent("CameraImage" + IntToStr(globalCameraIndex + 1));

              // offset 적용 시 변화하는 gain값을 적용해야하는데 일단 skip한다. (2022-06-22 moon)
							GetNFACamera2DColorImage(DestImage->Picture->Bitmap, CaptureData, MAX_IMAGE_WIDTH, MAX_IMAGE_HEIGHT, globalCameraIndex, false, NULL, ProductData.SubSamplingMode);

							// For SELMA200, 영상 반전 수정 예정
							if (globalCameraIndex == SD2_2D_SIDE_FACE_P45_CAMERA_INDEX - 1 ||
								globalCameraIndex == SD2_2D_SIDE_FACE_M45_CAMERA_INDEX - 1)
							{
								byte *pTempLine = new byte[DestImage->Picture->Bitmap->Width * 3];
								for (int y = 0; y < (DestImage->Picture->Bitmap->Height); y++)
								{
									byte *pBitmap = (byte *)DestImage->Picture->Bitmap->ScanLine[y];

									for (int x = 0; x < DestImage->Picture->Bitmap->Width; x++)
									{
										pTempLine[x * 3 + 0] = pBitmap[(DestImage->Picture->Bitmap->Width - 1 - x) * 3 + 0];
										pTempLine[x * 3 + 1] = pBitmap[(DestImage->Picture->Bitmap->Width - 1 - x) * 3 + 1];
										pTempLine[x * 3 + 2] = pBitmap[(DestImage->Picture->Bitmap->Width - 1 - x) * 3 + 2];
									}
									memcpy(pBitmap, pTempLine, DestImage->Picture->Bitmap->Width * 3);
								}
								delete[] pTempLine;
							}
							else if (globalCameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1 ||
								globalCameraIndex == SD2_2D_FRONT_FACE_CAMERA_INDEX - 1 ||
								globalCameraIndex == SD1_2D_SIDE_FACE_00_CAMERA_INDEX - 1 ||
								globalCameraIndex == SD1_2D_OTHER_SIDE_FACE_00_CAMERA_INDEX - 1 ||
								globalCameraIndex == SD1_2D_SIDE_FACE_P45_CAMERA_INDEX - 1 ||
								globalCameraIndex == SD1_2D_OTHER_SIDE_FACE_P45_CAMERA_INDEX - 1 ||
								globalCameraIndex == SD1_2D_SIDE_FACE_M45_CAMERA_INDEX - 1 ||
								globalCameraIndex == SD1_2D_OTHER_SIDE_FACE_M45_CAMERA_INDEX - 1)
							{
								byte *pTempLineT = new byte[DestImage->Picture->Bitmap->Width * 3];
								byte *pTempLineB = new byte[DestImage->Picture->Bitmap->Width * 3];
								for (int y = 0; y < (DestImage->Picture->Bitmap->Height + 1) / 2; y++)
								{
									byte *pBitmapT = (byte *)DestImage->Picture->Bitmap->ScanLine[y];
									byte *pBitmapB = (byte *)DestImage->Picture->Bitmap->ScanLine[DestImage->Picture->Bitmap->Height - 1 - y];

									memcpy(pTempLineT, pBitmapB, DestImage->Picture->Bitmap->Width * 3);
									memcpy(pTempLineB, pBitmapT, DestImage->Picture->Bitmap->Width * 3);
									memcpy(pBitmapT, pTempLineT, DestImage->Picture->Bitmap->Width * 3);
									memcpy(pBitmapB, pTempLineB, DestImage->Picture->Bitmap->Width * 3);
								}
								delete[] pTempLineT;
								delete[] pTempLineB;
							}

							if (SaveBmpCheckBox->Checked)
							{
								if (processingStep == PROCESSING_STEP_GET_BACKGROUND_INFO || processingStep == PROCESSING_STEP_GET_OBJECT_INFO)
								{
									AnsiString pathName = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\ETC Images";

									if (!DirectoryExists(pathName)) ForceDirectories(pathName);

									if (processingStep == PROCESSING_STEP_GET_BACKGROUND_INFO)
									{
										pathName = pathName + "\\Background";
									}
									else
									{
										pathName = pathName + "\\Object";
									}

									TProgressBar *tempProgressBar;
									tempProgressBar = (TProgressBar *)FindComponent("ProgressBarCam" + IntToStr(globalCameraIndex + 1));

									if (tempProgressBar)
									{
										if (!DirectoryExists(pathName)) ForceDirectories(pathName);

										pathName = pathName + "\\Image" + IntToStr(tempProgressBar->Position + 1) + "_C" + IntToStr(globalCameraIndex + 1) + ".bmp";
										DestImage->Picture->Bitmap->SaveToFile(pathName);
									}
								}
							}

							if (processingStep == PROCESSING_STEP_GET_BACKGROUND_INFO)
							{
								if (BackgroundImageStudyCount[globalCameraIndex] < MAX_BACKGROUND_STUDY_COUNT)
								{
									AccBackgroundImage(DestImage, globalCameraIndex);
									BackgroundImageStudyCount[globalCameraIndex]++;
								}
							}
							else if (processingStep == PROCESSING_STEP_GET_OBJECT_INFO)
							{
								if (globalCameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1 || globalCameraIndex == SD2_2D_FRONT_FACE_CAMERA_INDEX - 1)
								{
									SetFrontFaceObjectArea(DestImage, globalCameraIndex);
								}
								else
								{
									SetSideFaceObjectArea(DestImage, globalCameraIndex);
								}
							}
							else if (processingStep == PROCESSING_STEP_SET_MAIN_CAMERA_BRIGHTNESS || processingStep == PROCESSING_STEP_SET_SUB_CAMERA_BRIGHTNESS)
							{
								CheckTabletBrightness(DestImage, globalCameraIndex);
							}
							else if (processingStep == PROCESSING_STEP_CHECK_CAMERA_BRIGHTNESS)
							{
								ViewTabletBrightness(DestImage, globalCameraIndex);
							}

							DestImage->Canvas->Pen->Width = 3;

							if (brightnessStudyCompleted[globalCameraIndex] == CAMERA_BRIGHTNESS_CHECK_COMPLETED)
							{
								DestImage->Canvas->Pen->Color = clGreen;
							}
							else
							{
								DestImage->Canvas->Pen->Color = clYellow;
							}

							DestImage->Canvas->Brush->Style = bsClear;
							DestImage->Canvas->Rectangle(0, 0, DestImage->Picture->Bitmap->Width, DestImage->Picture->Bitmap->Height);
							DestImage->Repaint();

							TProgressBar *tempProgressBar;
							tempProgressBar = (TProgressBar *)FindComponent("ProgressBarCam" + IntToStr(globalCameraIndex + 1));

							if (tempProgressBar)
							{
								tempProgressBar->Position++;
								if (tempProgressBar->Position == tempProgressBar->Max)
								{
									tempProgressBar->Position = tempProgressBar->Min;
								}
							}
						}
					}
				}
				catch (...)
				{
					MessageDlgFA(TextMsgString[13], mtConfirmation, TMsgDlgButtons() << mbOK);

					CaptureStop();
					ImageLoadTimer->Enabled = false;

					processingStep = PROCESSING_STEP_NONE;
					MachineControl();
					InitResultComponent();

					SetActiveComponents(false);
					StartButton->Caption = MACHINESETTINGTESTFORM_BUTTON_CAPTION_07;

					return;
				}
			}
		}
	}

	if (processingStep == PROCESSING_STEP_SET_MAIN_CAMERA_BRIGHTNESS || processingStep == PROCESSING_STEP_SET_SUB_CAMERA_BRIGHTNESS)
	{
		// refresh camera brightness
		// 카메라 사용 중 데이터를 write하게 되면 영상에 노이즈가 발생함. 중지 후 재시작
    bool allCompleted = true;
    for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
    {
      if (ImageCaptureActiveCamera[globalCameraIndex])
      {
        if(checkedSW[globalCameraIndex] == false)
        {
          allCompleted = false;
        }
      }
    }

    if(allCompleted)
    {
		  CaptureStop();

      Sleep(100);

      if (SendSPBCaptureSetup())
      {
        TCaptureCommandParam_HCB captureCommandParam_HCB;
        captureCommandParam_HCB.Action = 1;
        captureCommandParam_HCB.FrameTime = StrToFloat(FrameTimeEdit->Text) * 20 + 0.5;
        captureCommandParam_HCB.LEDMask[0] = 0x00FFFFFF;
        captureCommandParam_HCB.LEDOnTime[0] = StrToFloat(LedOnTimeEdit->Text) * 20 + 0.5;
        captureCommandParam_HCB.ShutterDelay = StrToFloat(ShutterDelayEdit->Text) * 20 + 0.5;
        Comm_Request(COMM_HCB, CMD_TABLET_CAPTURE, &captureCommandParam_HCB, sizeof(TCaptureCommandParam_HCB), NULL, 0);
      }

      for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
      {
        checkedSW[globalCameraIndex] = false;
      }
    }

		bool studyCompleted = true;
		bool StudyFailed = false;
		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
			if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_DISCONNECT &&
				CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D && SystemLinkCameraInfo[globalCameraIndex] != 0)
			{
				if (ImageCaptureActiveCamera[globalCameraIndex])
				{
					if (brightnessStudyCompleted[globalCameraIndex] == CAMERA_BRIGHTNESS_CHECK_NONE)
					{
						studyCompleted = false;
					}
					else if (brightnessStudyCompleted[globalCameraIndex] == CAMERA_BRIGHTNESS_CHECK_FAILED)
					{
						StudyFailed = true;
					}
				}
			}
		}

		if (StudyFailed)
		{
			MessageDlgFA(TextMsgString[14], mtConfirmation, TMsgDlgButtons() << mbOK);

			CaptureStop();
			ImageLoadTimer->Enabled = false;

			processingStep = PROCESSING_STEP_NONE;
			MachineControl();
			InitResultComponent();

			SetActiveComponents(false);
			StartButton->Caption = MACHINESETTINGTESTFORM_BUTTON_CAPTION_07;

			return;
		}
		else if (studyCompleted)
		{
			StartButton->Enabled = true;
		}
	}

	if (processingStep == PROCESSING_STEP_GET_BACKGROUND_INFO)
	{
		if (globalStudySW == false)
		{
			bool studyComplete = true;
			for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
			{
				if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_DISCONNECT &&
					CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D && SystemLinkCameraInfo[globalCameraIndex] != 0)
				{
					if (ImageCaptureActiveCamera[globalCameraIndex])
					{
						if (BackgroundImageStudyCount[globalCameraIndex] < MAX_BACKGROUND_STUDY_COUNT)
						{
							studyComplete = false;
						}
					}
				}
			}

			if (studyComplete)
			{
				for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
				{
					if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_DISCONNECT &&
						CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D && SystemLinkCameraInfo[globalCameraIndex] != 0)
					{
						if (ImageCaptureActiveCamera[globalCameraIndex])
						{
							GetBackgroundImage(globalCameraIndex);
						}
					}
				}

				StartButton->Enabled = true;
				StopButton->Enabled = true;

				globalStudySW = true;
			}
		}
		else
		{
			if (ViewBgmImageCheckBox->Checked && globalStudySW)
			{
				for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
				{
					if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_DISCONNECT &&
						CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D && SystemLinkCameraInfo[globalCameraIndex] != 0)
					{
						if (ImageCaptureActiveCamera[globalCameraIndex])
						{
							TTntImage *DestImage;
							DestImage = (TTntImage *)FindComponent("CameraImage" + IntToStr(globalCameraIndex + 1));

							if (DestImage)
							{
								ViewBackgroundImage(DestImage, globalCameraIndex);
							}
						}
					}
				}
			}
		}
	}

	WideString timeoutCamera = "";
	bool cameraInactive = false;
	int inActiveCameraCount = 0;
  int ErrorCameraTime[SYSTEM_TOTAL_CAMERA_COUNT];
  memset(ErrorCameraTime, 0, sizeof(int) * SYSTEM_TOTAL_CAMERA_COUNT);

	for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	{
		if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_DISCONNECT &&
			CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D && SystemLinkCameraInfo[globalCameraIndex] != 0)
		{
			if (ImageCaptureActiveCamera[globalCameraIndex])
			{
				int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;

				if (Comm_IsConnected(COMM_SPB + spbIndex))
				{
					double currentTime = Now().Val;
					if ((currentTime - cameraActiveCheckTime[globalCameraIndex]) * 24 * 3600 > CAMERA_INACTIVE_CHECK_TIME)
					{
            ErrorCameraTime[globalCameraIndex] = (currentTime - cameraActiveCheckTime[globalCameraIndex]) * 24 * 3600;
						cameraInactive = true;
						inActiveCameraCount++;
					}
				}
			}
		}
	}

	if (cameraInactive)
	{
		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
			if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_DISCONNECT &&
				CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D && SystemLinkCameraInfo[globalCameraIndex] != 0)
			{
				if (ErrorCameraTime[globalCameraIndex])
				{
					timeoutCamera += "C" + IntToStr(globalCameraIndex + 1) + "(" + IntToStr(ErrorCameraTime[globalCameraIndex]) + "s)";

					inActiveCameraCount--;
					if (inActiveCameraCount)
					{
					  timeoutCamera += ", ";
					}
				}
			}
		}

		MessageDlgFA(TextMsgString[15] + "[" + timeoutCamera + "]", mtConfirmation, TMsgDlgButtons() << mbOK);

		CaptureStop();
		timerEnabled = false;

		processingStep = PROCESSING_STEP_NONE;
		MachineControl();
		InitResultComponent();

		SetActiveComponents(false);
		StartButton->Caption = MACHINESETTINGTESTFORM_BUTTON_CAPTION_07;
	}

	ImageLoadTimer->Enabled = timerEnabled;
}
//---------------------------------------------------------------------------

void __fastcall TAutoBrightnessSettingForm::RefreshEnabledCamera()
{
	for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	{
		CameraComponentInitSW[globalCameraIndex] = false;
	}

	if (processingStep == PROCESSING_STEP_NONE)
	{
		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
			ImageCaptureActiveCamera[globalCameraIndex] = false;
		}
	}
	else if (processingStep == PROCESSING_STEP_GET_BACKGROUND_INFO || processingStep == PROCESSING_STEP_GET_OBJECT_INFO)
	{
		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
			ImageCaptureActiveCamera[globalCameraIndex] = false;

			if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_DISCONNECT &&
				CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D && SystemLinkCameraInfo[globalCameraIndex] != 0)
			{
				int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;

				if (Comm_IsConnected(COMM_SPB + spbIndex))
				{
					ImageCaptureActiveCamera[globalCameraIndex] = true;
				}
			}
		}
	}
	else if (processingStep == PROCESSING_STEP_SET_MAIN_CAMERA_BRIGHTNESS)
	{
		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
			ImageCaptureActiveCamera[globalCameraIndex] = false;

			if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_DISCONNECT &&
				CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D && SystemLinkCameraInfo[globalCameraIndex] != 0)
			{
				if (globalCameraIndex == ActiveVerticalCameraIndex - 1 || globalCameraIndex == ActiveSideCameraIndex - 1)
				{
					int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;

					if (Comm_IsConnected(COMM_SPB + spbIndex))
					{
						ImageCaptureActiveCamera[globalCameraIndex] = true;
					}
				}
			}
		}
	}
	else if (processingStep == PROCESSING_STEP_SET_SUB_CAMERA_BRIGHTNESS)
	{
		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
			ImageCaptureActiveCamera[globalCameraIndex] = false;

			if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_DISCONNECT &&
				CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D && SystemLinkCameraInfo[globalCameraIndex] != 0)
			{
				if (globalCameraIndex != ActiveVerticalCameraIndex - 1 && globalCameraIndex != ActiveSideCameraIndex - 1)
				{
					int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;

					if (Comm_IsConnected(COMM_SPB + spbIndex))
					{
						ImageCaptureActiveCamera[globalCameraIndex] = true;
					}
				}
			}
		}
	}
	else if (processingStep == PROCESSING_STEP_CHECK_CAMERA_BRIGHTNESS)
	{
		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
			ImageCaptureActiveCamera[globalCameraIndex] = false;

			if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_DISCONNECT &&
				CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D && SystemLinkCameraInfo[globalCameraIndex] != 0)
			{
				int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;

				if (Comm_IsConnected(COMM_SPB + spbIndex))
				{
					ImageCaptureActiveCamera[globalCameraIndex] = true;
				}
			}
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TAutoBrightnessSettingForm::RefreshInactiveCameraComponent()
{
	for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	{
		if (ImageCaptureActiveCamera[globalCameraIndex] == false && CameraComponentInitSW[globalCameraIndex] == false)
		{
			CameraComponentInitSW[globalCameraIndex] = true;

			TProgressBar *tempProgressBar = (TProgressBar *)FindComponent("ProgressBarCam" + IntToStr(globalCameraIndex + 1));

			if (tempProgressBar)
			{
				tempProgressBar->Position = 0;
				tempProgressBar->Refresh();
			}

			TTntImage *CameraImage = (TTntImage *)FindComponent("CameraImage" + IntToStr(globalCameraIndex + 1));

			if (CameraImage)
			{
				CameraImage->Picture->Bitmap->Width = SYSTEM_CAMERA_WIDTH;
				CameraImage->Picture->Bitmap->Height = MAX_IMAGE_HEIGHT;
				CameraImage->Picture->Bitmap->PixelFormat = pf24bit;

				CameraImage->Canvas->Brush->Color = clBlack;
				CameraImage->Canvas->Brush->Style = bsSolid;
				CameraImage->Canvas->FillRect(Rect(0, 0, CameraImage->Picture->Bitmap->Width, CameraImage->Picture->Bitmap->Height));

				CameraImage->Refresh();
			}

			TTntPanel *CameraBrightnessValuePanel = (TTntPanel *)FindComponent("CameraBrightnessValuePanel" + IntToStr(globalCameraIndex + 1));

			if (CameraBrightnessValuePanel)
			{
				CameraBrightnessValuePanel->Caption = "N/A";

				CameraBrightnessValuePanel->Refresh();
			}
		}
	}
}

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

void __fastcall TAutoBrightnessSettingForm::MachineControl()
{
	if (processingStep == PROCESSING_STEP_GET_BACKGROUND_INFO)
	{
		int motorIndex;
		int baseSpeed;
		int targetSpeed;
		int accTime;
		int dir;

		// DISK1
		motorIndex = 0;
		baseSpeed = MachineSetupData.ServoMotorData[motorIndex].BaseSpeed;
		targetSpeed = ProductData.StudyMotorSpeedList[motorIndex][0];
		accTime = MachineSetupData.ServoMotorData[motorIndex].AccTime;
		dir = 0;

		if (MachineSetupData.ServoMotorData[motorIndex].Dir)
		{
			dir = 1;
		}
		else
		{
			dir = 0;
		}
		Machine.ServoMotorRun(motorIndex, baseSpeed, targetSpeed, accTime, dir);

		// DISK2
		motorIndex = 1;
		baseSpeed = MachineSetupData.ServoMotorData[motorIndex].BaseSpeed;
		targetSpeed = ProductData.StudyMotorSpeedList[motorIndex][0];
		accTime = MachineSetupData.ServoMotorData[motorIndex].AccTime;
		dir = 0;

		if (MachineSetupData.ServoMotorData[motorIndex].Dir)
		{
			dir = 1;
		}
		else
		{
			dir = 0;
		}
		Machine.ServoMotorRun(motorIndex, baseSpeed, targetSpeed, accTime, dir);

		StartButton->Enabled = false;
		StopButton->Enabled = false;
		MachineControlPanel->Visible = true;
		double motorRunTime = Now().Val;
		while (1)
		{
			Application->ProcessMessages();

			double currentTime = Now().Val;

			if ((currentTime - motorRunTime) * 24 * 3600 > SERVO_MOTOR_SPEED_STABLE_TIME)
			{
				MachineControlPanel->Visible = false;
				break;
			}
		}
	}
	else if (processingStep == PROCESSING_STEP_GET_OBJECT_INFO)
	{
		// motor stop
		int decTime;
		decTime = MachineSetupData.ServoMotorData[0].DecTime;
		Machine.ServoMotorStop(0, decTime);
		decTime = MachineSetupData.ServoMotorData[1].DecTime;
		Machine.ServoMotorStop(1, decTime);

		StartButton->Enabled = false;
		StopButton->Enabled = false;
		MachineControlPanel->Visible = true;
		double motorRunTime = Now().Val;
		while (1)
		{
			Application->ProcessMessages();

			float Disk1RealRPM = Machine.GetServoMotorRPM(0);
			float Disk2RealRPM = Machine.GetServoMotorRPM(1);

			double currentTime = Now().Val;

			if (((currentTime - motorRunTime) * 24 * 3600 > MAX_SERVO_MOTOR_STOPPING_TIME)
				|| (Disk1RealRPM < 0.1 && Disk2RealRPM < 0.1))
			{
				StartButton->Enabled = true;
				StopButton->Enabled = true;
				MachineControlPanel->Visible = false;
				break;
			}
		}

		int speed1 = 255;
		int speed2 = 255;

		Machine.RingBlowerOn(0, speed1, speed2);
		Machine.RingBlowerOn(1, speed1, speed2);
	}
	else if (processingStep == PROCESSING_STEP_SET_MAIN_CAMERA_BRIGHTNESS || processingStep == PROCESSING_STEP_SET_SUB_CAMERA_BRIGHTNESS || processingStep == PROCESSING_STEP_CHECK_CAMERA_BRIGHTNESS)
	{
		int speed1 = 255;
		int speed2 = 255;

		Machine.RingBlowerOn(0, speed1, speed2);
		Machine.RingBlowerOn(1, speed1, speed2);

		if (processingStep == PROCESSING_STEP_SET_MAIN_CAMERA_BRIGHTNESS || processingStep == PROCESSING_STEP_SET_SUB_CAMERA_BRIGHTNESS)
		{
			StartButton->Enabled = false;
		}
		else
		{
			StartButton->Enabled = true;
		}
		StopButton->Enabled = true;
	}
	else if (processingStep == PROCESSING_STEP_COMPLETE || processingStep == PROCESSING_STEP_NONE)
	{
		// motor stop
		int decTime;
		decTime = MachineSetupData.ServoMotorData[0].DecTime;
		Machine.ServoMotorStop(0, decTime);
		decTime = MachineSetupData.ServoMotorData[1].DecTime;
		Machine.ServoMotorStop(1, decTime);

		StartButton->Enabled = false;
		StopButton->Enabled = false;
		MachineControlPanel->Visible = true;
		double motorRunTime = Now().Val;
		while (1)
		{
			Application->ProcessMessages();

			float Disk1RealRPM = Machine.GetServoMotorRPM(0);
			float Disk2RealRPM = Machine.GetServoMotorRPM(1);

			double currentTime = Now().Val;

			if (((currentTime - motorRunTime) * 24 * 3600 > MAX_SERVO_MOTOR_STOPPING_TIME)
				|| (Disk1RealRPM < 0.1 && Disk2RealRPM < 0.1))
			{
				StartButton->Enabled = true;
				StopButton->Enabled = true;
				MachineControlPanel->Visible = false;
				break;
			}
		}

		Machine.RingBlowerOff(0);
		Machine.RingBlowerOff(1);
	}
}

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

void __fastcall TAutoBrightnessSettingForm::InitImageBuffer()
{
	memset(BackgroundImage, 0, SYSTEM_TOTAL_CAMERA_COUNT * MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * 3 * sizeof(int));
	memset(ObjectAreaImage, 0, SYSTEM_TOTAL_CAMERA_COUNT * MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	memset(BackgroundImageStudyCount, 0, SYSTEM_TOTAL_CAMERA_COUNT * sizeof(int));
	memset(sideCenterPosDataCount, 0, SYSTEM_TOTAL_CAMERA_COUNT * sizeof(int));
}

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

void __fastcall TAutoBrightnessSettingForm::AccBackgroundImage(TTntImage *srcImage, int cameraIndex)
{
	int x, y;
	Byte *ptr;
	int tempAddress;

	for (y = 0; y < MAX_IMAGE_HEIGHT; y++)
	{
		ptr = (Byte*)srcImage->Picture->Bitmap->ScanLine[y];
		for (x = 0; x < MAX_IMAGE_WIDTH; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;

			BackgroundImage[cameraIndex][tempAddress * 3 + 0] += ptr[3 * x + 0];
			BackgroundImage[cameraIndex][tempAddress * 3 + 1] += ptr[3 * x + 1];
			BackgroundImage[cameraIndex][tempAddress * 3 + 2] += ptr[3 * x + 2];
		}
	}
}

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

void __fastcall TAutoBrightnessSettingForm::GetBackgroundImage(int cameraIndex)
{
	int x, y;
	int tempAddress;
	int value[3];

	for (y = 0; y < MAX_IMAGE_HEIGHT; y++)
	{
		for (x = 0; x < MAX_IMAGE_WIDTH; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;

			if (BackgroundImageStudyCount[cameraIndex])
			{
				value[0] = BackgroundImage[cameraIndex][tempAddress * 3 + 0] / BackgroundImageStudyCount[cameraIndex];
				value[1] = BackgroundImage[cameraIndex][tempAddress * 3 + 1] / BackgroundImageStudyCount[cameraIndex];
				value[2] = BackgroundImage[cameraIndex][tempAddress * 3 + 2] / BackgroundImageStudyCount[cameraIndex];
			}
			else
			{
				value[0] = value[1] = value[2] = 0;
			}

			if (value[0] > 0 && value[0] < 256)
			{
				BackgroundImage[cameraIndex][tempAddress * 3 + 0] = value[0];
			}
			else
			{
				BackgroundImage[cameraIndex][tempAddress * 3 + 0] = 0;
			}

			if (value[1] > 0 && value[1] < 256)
			{
				BackgroundImage[cameraIndex][tempAddress * 3 + 1] = value[1];
			}
			else
			{
				BackgroundImage[cameraIndex][tempAddress * 3 + 1] = 0;
			}

			if (value[2] > 0 && value[2] < 256)
			{
				BackgroundImage[cameraIndex][tempAddress * 3 + 2] = value[2];
			}
			else
			{
				BackgroundImage[cameraIndex][tempAddress * 3 + 2] = 0;
			}
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TAutoBrightnessSettingForm::GroupBox3DblClick(
	TObject *Sender)
{
	ViewBgmImageCheckBox->Visible = !ViewBgmImageCheckBox->Visible;
}
//---------------------------------------------------------------------------

void __fastcall TAutoBrightnessSettingForm::ViewBackgroundImage(TTntImage *DestImage, int cameraIndex)
{
	int x, y;
	Byte *ptr;
	int tempAddress;

	for (y = 0; y < MAX_IMAGE_HEIGHT; y++)
	{
		ptr = (Byte*)DestImage->Picture->Bitmap->ScanLine[y];
		for (x = 0; x < MAX_IMAGE_WIDTH; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;

			ptr[3 * x + 0] = BackgroundImage[cameraIndex][tempAddress * 3 + 0];
			ptr[3 * x + 1] = BackgroundImage[cameraIndex][tempAddress * 3 + 1];
			ptr[3 * x + 2] = BackgroundImage[cameraIndex][tempAddress * 3 + 2];
		}
	}

	DestImage->Refresh();
}

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

void __fastcall TAutoBrightnessSettingForm::SetFrontFaceObjectArea(TTntImage *srcImage, int cameraIndex)
{
	memset(ObjectAreaImage[cameraIndex], 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	sideCenterPosDataCount[cameraIndex] = 0;

	int x, y;
	Byte *ptr;
	int tempAddress, tempAddress2;
	int colorDiff[3];
	int RGBValue[3];
	int maxValue;
	int colorSum;
	int searchingCount, validBinCount;
	int r;
	int noiseCount;
	int maxRGBCount[3];
	int rgb;
	int colorRate[3];
	int tempCount;
	int value;
	int avgTabletColorRate;
	int chromaticThreshold;
	int mostRGB;
	int srcColorRate;
	int leftSW, rightSW, topSW, bottomSW;

	int startX, endX, startY, endY;
	startX = 10;
	endX = MAX_IMAGE_WIDTH - 10;
	startY = 10;
	endY = MAX_IMAGE_HEIGHT - 10;

	memset(HalfLabelImage, 0, (MAX_IMAGE_WIDTH / 2) * (MAX_IMAGE_HEIGHT / 2) * sizeof(short));
	memset(smallBinaryImage, 0, (MAX_IMAGE_WIDTH / 2) * (MAX_IMAGE_HEIGHT / 2));
	memset(maxRGBFactorSrcArry, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	memset(maxRGBFactorOstArry, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	memset(ColorRateImageSrcArr, 0, sizeof(short) * MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * 3);
	memset(ColorRateImageOstArr, 0, sizeof(short) * MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * 3);

	int maxRGBFactor = 1;

	if (!SimulationCheckBox->Checked)
	{
		memset(ColorSourceImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * 3);

		unsigned char *darknessArea;
		unsigned char *brightnessArea;

		darknessArea = TempImage2;
		brightnessArea = TempImage3;

		memset(darknessArea, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		memset(brightnessArea, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

		for (y = startY; y < endY; y++)
		{
			ptr = (Byte*)srcImage->Picture->Bitmap->ScanLine[y];
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				ColorSourceImage[tempAddress * 3 + 0] = ptr[3 * x + 0];
				ColorSourceImage[tempAddress * 3 + 1] = ptr[3 * x + 1];
				ColorSourceImage[tempAddress * 3 + 2] = ptr[3 * x + 2];

				if (ColorSourceImage[tempAddress * 3 + 0] > MIN_OBJECT_BRIGHTNESS ||
					ColorSourceImage[tempAddress * 3 + 1] > MIN_OBJECT_BRIGHTNESS ||
					ColorSourceImage[tempAddress * 3 + 2] > MIN_OBJECT_BRIGHTNESS)
				{
					colorDiff[0] = ColorSourceImage[tempAddress * 3 + 0] - BackgroundImage[cameraIndex][tempAddress * 3 + 0];
					colorDiff[1] = ColorSourceImage[tempAddress * 3 + 1] - BackgroundImage[cameraIndex][tempAddress * 3 + 1];
					colorDiff[2] = ColorSourceImage[tempAddress * 3 + 2] - BackgroundImage[cameraIndex][tempAddress * 3 + 2];

					if (abs(colorDiff[0]) > MIN_OBJECT_COLOR_DIFF || abs(colorDiff[1]) > MIN_OBJECT_COLOR_DIFF || abs(colorDiff[2]) > MIN_OBJECT_COLOR_DIFF) // 잡음성 데이터 제거 위함
					{
						ObjectAreaImage[cameraIndex][tempAddress] = 1;
					}
				}
			}
		}

		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (ObjectAreaImage[cameraIndex][tempAddress])
				{
					RGBValue[0] = ColorSourceImage[tempAddress * 3 + 0];
					RGBValue[1] = ColorSourceImage[tempAddress * 3 + 1];
					RGBValue[2] = ColorSourceImage[tempAddress * 3 + 2];

					maxValue = max(RGBValue[0], max(RGBValue[1], RGBValue[2]));

					if (maxValue == RGBValue[0])
					{
						maxRGBFactorSrcArry[tempAddress] = 1;
					}
					else if (maxValue == RGBValue[1])
					{
						maxRGBFactorSrcArry[tempAddress] = 2;
					}
					else if (maxValue == RGBValue[2])
					{
						maxRGBFactorSrcArry[tempAddress] = 3;
					}

					colorSum = RGBValue[0] + RGBValue[1] + RGBValue[2];
					if (colorSum)
					{
						ColorRateImageSrcArr[tempAddress * 3 + 0] = RGBValue[0] * 1000 / colorSum;
						ColorRateImageSrcArr[tempAddress * 3 + 1] = RGBValue[1] * 1000 / colorSum;
						ColorRateImageSrcArr[tempAddress * 3 + 2] = RGBValue[2] * 1000 / colorSum;
					}

					RGBValue[0] = BackgroundImage[cameraIndex][tempAddress * 3 + 0];
					RGBValue[1] = BackgroundImage[cameraIndex][tempAddress * 3 + 1];
					RGBValue[2] = BackgroundImage[cameraIndex][tempAddress * 3 + 2];

					maxValue = max(RGBValue[0], max(RGBValue[1], RGBValue[2]));

					if (maxValue == RGBValue[0])
					{
						maxRGBFactorOstArry[tempAddress] = 1;
					}
					else if (maxValue == RGBValue[1])
					{
						maxRGBFactorOstArry[tempAddress] = 2;
					}
					else if (maxValue == RGBValue[2])
					{
						maxRGBFactorOstArry[tempAddress] = 3;
					}

					colorSum = RGBValue[0] + RGBValue[1] + RGBValue[2];
					if (colorSum)
					{
						ColorRateImageOstArr[tempAddress * 3 + 0] = RGBValue[0] * 1000 / colorSum;
						ColorRateImageOstArr[tempAddress * 3 + 1] = RGBValue[1] * 1000 / colorSum;
						ColorRateImageOstArr[tempAddress * 3 + 2] = RGBValue[2] * 1000 / colorSum;
					}
				}
			}
		}

		memcpy(TempImage, ObjectAreaImage[cameraIndex], MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (TempImage[tempAddress])
				{
					if (maxRGBFactorSrcArry[tempAddress] != maxRGBFactorOstArry[tempAddress])
					{
						searchingCount = validBinCount = 0;
						for (r = 12; r >= 4; r -= 4)
						{
							if (x - r > startX)
							{
								searchingCount++;
								tempAddress2 = tempAddress - r;
								if (maxRGBFactorSrcArry[tempAddress] != maxRGBFactorOstArry[tempAddress2])
								{
									validBinCount++;
								}
							}

							if (x + r < endX)
							{
								searchingCount++;
								tempAddress2 = tempAddress + r;
								if (maxRGBFactorSrcArry[tempAddress] != maxRGBFactorOstArry[tempAddress2])
								{
									validBinCount++;
								}
							}

							if (y - r > startY)
							{
								searchingCount++;
								tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH;
								if (maxRGBFactorSrcArry[tempAddress] != maxRGBFactorOstArry[tempAddress2])
								{
									validBinCount++;
								}
							}

							if (y + r < endY)
							{
								searchingCount++;
								tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH;
								if (maxRGBFactorSrcArry[tempAddress] != maxRGBFactorOstArry[tempAddress2])
								{
									validBinCount++;
								}
							}

							if (x - r > startX && y - r > startY)
							{
								searchingCount++;
								tempAddress2 = tempAddress - r - r * MAX_IMAGE_WIDTH;
								if (maxRGBFactorSrcArry[tempAddress] != maxRGBFactorOstArry[tempAddress2])
								{
									validBinCount++;
								}
							}

							if (x - r > startX && y - r < endY)
							{
								searchingCount++;
								tempAddress2 = tempAddress - r + r * MAX_IMAGE_WIDTH;
								if (maxRGBFactorSrcArry[tempAddress] != maxRGBFactorOstArry[tempAddress2])
								{
									validBinCount++;
								}
							}

							if (x + r < endX && y - r > startY)
							{
								searchingCount++;
								tempAddress2 = tempAddress + r - r * MAX_IMAGE_WIDTH;
								if (maxRGBFactorSrcArry[tempAddress] != maxRGBFactorOstArry[tempAddress2])
								{
									validBinCount++;
								}
							}

							if (x + r < endX && y - r < endY)
							{
								searchingCount++;
								tempAddress2 = tempAddress + r + r * MAX_IMAGE_WIDTH;
								if (maxRGBFactorSrcArry[tempAddress] != maxRGBFactorOstArry[tempAddress2])
								{
									validBinCount++;
								}
							}
						}

						if (searchingCount)
						{
							if (searchingCount * 4 / 5 < validBinCount)
							{
								ObjectAreaImage[cameraIndex][tempAddress] = 2;
							}
						}
					}
					else
					{
						mostRGB = maxRGBFactorSrcArry[tempAddress] - 1;
						colorDiff[mostRGB] = abs(ColorRateImageSrcArr[tempAddress * 3 + mostRGB] - ColorRateImageOstArr[tempAddress * 3 + mostRGB]);

						if (colorDiff[mostRGB] > 50)
						{
							ObjectAreaImage[cameraIndex][tempAddress] = 2;
						}
						else if (ColorSourceImage[tempAddress * 3 + 0] - BackgroundImage[cameraIndex][tempAddress * 3 + 0] < 4 &&
							ColorSourceImage[tempAddress * 3 + 1] - BackgroundImage[cameraIndex][tempAddress * 3 + 1] < 4 &&
							ColorSourceImage[tempAddress * 3 + 2] - BackgroundImage[cameraIndex][tempAddress * 3 + 2] < 4)
						{
							ObjectAreaImage[cameraIndex][tempAddress] = 0;
						}
					}
				}
			}
		}

		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (ObjectAreaImage[cameraIndex][tempAddress] == 1)
				{
					colorDiff[0] = ColorSourceImage[tempAddress * 3 + 0] - BackgroundImage[cameraIndex][tempAddress * 3 + 0];
					colorDiff[1] = ColorSourceImage[tempAddress * 3 + 1] - BackgroundImage[cameraIndex][tempAddress * 3 + 1];
					colorDiff[2] = ColorSourceImage[tempAddress * 3 + 2] - BackgroundImage[cameraIndex][tempAddress * 3 + 2];

					if (!(abs(colorDiff[0]) > MAX_OBJECT_COLOR_DIFF || abs(colorDiff[1]) > MAX_OBJECT_COLOR_DIFF || abs(colorDiff[2]) > MAX_OBJECT_COLOR_DIFF))
					{
						ObjectAreaImage[cameraIndex][tempAddress] = 0;
					}
				}
			}
		}

		memcpy(TempImage, ObjectAreaImage[cameraIndex], MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;
				if (TempImage[tempAddress])
				{
					noiseCount = 0;

					for (r = 4; r <= 8; r += 4)
					{
						if (y - r > startY)
						{
							tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH;
							if (TempImage[tempAddress2] == 0)
							{
								noiseCount++;
								break;
							}
						}
					}

					for (r = 4; r <= 8; r += 4)
					{
						if (y + r < endY)
						{
							tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH;
							if (TempImage[tempAddress2] == 0)
							{
								noiseCount++;
								break;
							}
						}
					}

					if (noiseCount == 2)
					{
						for (r = 4; r <= 8; r += 4)
						{
							if (x - r > startX)
							{
								tempAddress2 = tempAddress - r;
								if (TempImage[tempAddress2] == 0)
								{
									noiseCount++;
									break;
								}
							}
						}

						for (r = 4; r <= 8; r += 4)
						{
							if (x + r < endX)
							{
								tempAddress2 = tempAddress + r;
								if (TempImage[tempAddress2] == 0)
								{
									noiseCount++;
									break;
								}
							}
						}
					}

					if (noiseCount >= 3)
					{
						ObjectAreaImage[cameraIndex][tempAddress] = 0;
					}
				}
			}
		}

		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (ObjectAreaImage[cameraIndex][tempAddress])
				{
					colorDiff[0] = ColorSourceImage[tempAddress * 3 + 0] - BackgroundImage[cameraIndex][tempAddress * 3 + 0];
					colorDiff[1] = ColorSourceImage[tempAddress * 3 + 1] - BackgroundImage[cameraIndex][tempAddress * 3 + 1];
					colorDiff[2] = ColorSourceImage[tempAddress * 3 + 2] - BackgroundImage[cameraIndex][tempAddress * 3 + 2];

					if (abs(colorDiff[0]) > MAX_OBJECT_COLOR_DIFF || abs(colorDiff[1]) > MAX_OBJECT_COLOR_DIFF || abs(colorDiff[2]) > MAX_OBJECT_COLOR_DIFF)
					{
						if (abs(colorDiff[0]) > MAX_OBJECT_COLOR_DIFF)
						{
							if (colorDiff[0] > 0)
							{
								brightnessArea[tempAddress] = 1;
							}
							else
							{
								darknessArea[tempAddress] = 1;
							}
						}

						if (abs(colorDiff[1]) > MAX_OBJECT_COLOR_DIFF)
						{
							if (colorDiff[1] > 0)
							{
								brightnessArea[tempAddress] = 1;
							}
							else
							{
								darknessArea[tempAddress] = 1;
							}
						}

						if (abs(colorDiff[2]) > MAX_OBJECT_COLOR_DIFF)
						{
							if (colorDiff[2] > 0)
							{
								brightnessArea[tempAddress] = 1;
							}
							else
							{
								darknessArea[tempAddress] = 1;
							}
						}
					}
				}
			}
		}

		int DarkOrBrightTabletSW = 0;
		int tabletAreaCount = 0;
		int darkTabletAreaCount = 0;
		int brightTabletAreaCount = 0;
		for (y = startY; y < endY; y += 2)
		{
			for (x = startX; x < endX; x += 2)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (ObjectAreaImage[cameraIndex][tempAddress])
				{
					tabletAreaCount++;

					if (darknessArea[tempAddress])
					{
						darkTabletAreaCount++;
					}

					if (brightnessArea[tempAddress])
					{
						brightTabletAreaCount++;
					}
				}
			}
		}

		if (tabletAreaCount)
		{
			if (darkTabletAreaCount * 100 / tabletAreaCount > 95)
			{
				DarkOrBrightTabletSW = 1;
			}
			else if (brightTabletAreaCount * 100 / tabletAreaCount > 95)
			{
				DarkOrBrightTabletSW = 2;
			}

			// 예외케이스를 최대한 줄이기 위함
			// 정제 색상에 따라 배경과 비교한 결과가 뚜렷한 경우에는 해당 조건에 맞는 필터를 적용
		}


		memset(maxRGBCount, 0, sizeof(int) * 3);
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (ObjectAreaImage[cameraIndex][tempAddress])
				{
					if (maxRGBFactorSrcArry[tempAddress])
					{
						maxRGBCount[maxRGBFactorSrcArry[tempAddress] - 1]++;
					}
				}
			}
		}

		maxValue = 0;
		for (rgb = 0; rgb < 3; rgb++)
		{
			if (maxValue < maxRGBCount[rgb])
			{
				maxValue = maxRGBCount[rgb];
				maxRGBFactor = rgb;
			}
		}

		memset(colorRate, 0, sizeof(int) * 3);
		tempCount = 0;
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (ObjectAreaImage[cameraIndex][tempAddress])
				{
					value = maxRGBFactorSrcArry[tempAddress];
					if (value)
					{
						value = value - 1;

						if (value == maxRGBFactor)
						{
							colorRate[0] += ColorRateImageSrcArr[tempAddress * 3 + 0];
							colorRate[1] += ColorRateImageSrcArr[tempAddress * 3 + 1];
							colorRate[2] += ColorRateImageSrcArr[tempAddress * 3 + 2];
							tempCount++;
						}
					}
				}
			}
		}

		int chromaticTabletSW = 0;
		if (tempCount)
		{
			colorRate[0] /= tempCount;
			colorRate[1] /= tempCount;
			colorRate[2] /= tempCount;

			colorSum = colorRate[0] + colorRate[1] + colorRate[2];
			if (colorSum)
			{
				avgTabletColorRate = colorRate[maxRGBFactor] * 100 / colorSum;

				if (avgTabletColorRate >= CHROMATIC_TABLET_VALUE)
				{
					chromaticTabletSW = 1;
					chromaticThreshold = avgTabletColorRate * 0.9;
					for (y = startY; y < endY; y++)
					{
						for (x = startX; x < endX; x++)
						{
							tempAddress = MAX_IMAGE_WIDTH * y + x;

							if (maxRGBFactorSrcArry[tempAddress])
							{
								mostRGB = maxRGBFactorSrcArry[tempAddress] - 1;

								colorRate[0] = ColorRateImageSrcArr[tempAddress * 3 + 0];
								colorRate[1] = ColorRateImageSrcArr[tempAddress * 3 + 1];
								colorRate[2] = ColorRateImageSrcArr[tempAddress * 3 + 2];

								colorSum = colorRate[0] + colorRate[1] + colorRate[2];

								if (colorSum)
								{
									srcColorRate = colorRate[maxRGBFactor] * 100 / colorSum;

									if (srcColorRate < chromaticThreshold)
									{
										ObjectAreaImage[cameraIndex][tempAddress] = 0;
									}
								}
								else
								{
									ObjectAreaImage[cameraIndex][tempAddress] = 0;
								}
							}
						}
					}
				}
				else if (avgTabletColorRate >= CHROMATIC_TABLET_VALUE2)
				{
					for (y = startY; y < endY; y++)
					{
						for (x = startX; x < endX; x++)
						{
							tempAddress = MAX_IMAGE_WIDTH * y + x;

							if (maxRGBFactorSrcArry[tempAddress])
							{
								mostRGB = maxRGBFactorSrcArry[tempAddress] - 1;

								if (mostRGB != maxRGBFactor)
								{
									ObjectAreaImage[cameraIndex][tempAddress] = 0;
								}
							}
						}
					}
				}
			}
		}

		if (DarkOrBrightTabletSW == 2 || ((cameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1 || cameraIndex == SD2_2D_FRONT_FACE_CAMERA_INDEX - 1) && !chromaticTabletSW))
		{
			for (y = startY; y < endY; y++)
			{
				for (x = startX; x < endX; x++)
				{
					tempAddress = MAX_IMAGE_WIDTH * y + x;

					if (ObjectAreaImage[cameraIndex][tempAddress])
					{
						colorDiff[0] = ColorSourceImage[tempAddress * 3 + 0] - BackgroundImage[cameraIndex][tempAddress * 3 + 0];
						colorDiff[1] = ColorSourceImage[tempAddress * 3 + 1] - BackgroundImage[cameraIndex][tempAddress * 3 + 1];
						colorDiff[2] = ColorSourceImage[tempAddress * 3 + 2] - BackgroundImage[cameraIndex][tempAddress * 3 + 2];

						if (!(colorDiff[0] > MAX_OBJECT_COLOR_DIFF || colorDiff[1] > MAX_OBJECT_COLOR_DIFF || colorDiff[2] > MAX_OBJECT_COLOR_DIFF))
						{
							ObjectAreaImage[cameraIndex][tempAddress] = 0;
						}
					}
				}
			}
		}
		else if (DarkOrBrightTabletSW == 1)
		{
			for (y = startY; y < endY; y++)
			{
				for (x = startX; x < endX; x++)
				{
					tempAddress = MAX_IMAGE_WIDTH * y + x;

					if (ObjectAreaImage[cameraIndex][tempAddress])
					{
						colorDiff[0] = BackgroundImage[cameraIndex][tempAddress * 3 + 0] - ColorSourceImage[tempAddress * 3 + 0];
						colorDiff[1] = BackgroundImage[cameraIndex][tempAddress * 3 + 1] - ColorSourceImage[tempAddress * 3 + 1];
						colorDiff[2] = BackgroundImage[cameraIndex][tempAddress * 3 + 2] - ColorSourceImage[tempAddress * 3 + 2];

						if (!(colorDiff[0] > MAX_OBJECT_COLOR_DIFF || colorDiff[1] > MAX_OBJECT_COLOR_DIFF || colorDiff[2] > MAX_OBJECT_COLOR_DIFF))
						{
							ObjectAreaImage[cameraIndex][tempAddress] = 0;
						}
					}
				}
			}
		}

		memcpy(TempImage, ObjectAreaImage[cameraIndex], MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;
				if (TempImage[tempAddress] == 0)
				{
					leftSW = rightSW = bottomSW = topSW = 0;

					for (r = 12; r >= 4; r -= 4)
					{
						if (x - r > startX)
						{
							tempAddress2 = tempAddress - r;
							if (TempImage[tempAddress2])
							{
								leftSW = 1;
								break;
							}
						}
					}
					if (!leftSW) continue;

					for (r = 12; r >= 4; r -= 4)
					{
						if (x + r < endX)
						{
							tempAddress2 = tempAddress + r;
							if (TempImage[tempAddress2])
							{
								rightSW = 1;
								break;
							}
						}
					}
					if (!rightSW) continue;

					for (r = 12; r >= 4; r -= 4)
					{
						if (y - r > startY)
						{
							tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH;
							if (TempImage[tempAddress2])
							{
								topSW = 1;
								break;
							}
						}
					}
					if (!topSW) continue;

					for (r = 12; r >= 4; r -= 4)
					{
						if (y + r < endY)
						{
							tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH;
							if (TempImage[tempAddress2])
							{
								bottomSW = 1;
								break;
							}
						}
					}
					if (!bottomSW) continue;

					ObjectAreaImage[cameraIndex][tempAddress] = 1;
				}
			}
		}

		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;
				tempAddress2 = (MAX_IMAGE_WIDTH / 2) * (y / 2) + (x / 2);

				if (ObjectAreaImage[cameraIndex][tempAddress])
				{
					smallBinaryImage[tempAddress2] = 1;
				}
			}
		}

		int maxLabelN = LabellingForTabletImage(HalfLabelImage, smallBinaryImage, startX / 2, endX / 2, startY / 2, endY / 2, MAX_IMAGE_WIDTH / 2, MAX_IMAGE_HEIGHT / 2);

		if (maxLabelN)
		{
			for (y = startY; y < endY; y++)
			{
				for (x = startX; x < endX; x++)
				{
					tempAddress = MAX_IMAGE_WIDTH * y + x;
					tempAddress2 = (MAX_IMAGE_WIDTH / 2) * (y / 2) + (x / 2);

					if (ObjectAreaImage[cameraIndex][tempAddress])
					{
						if (HalfLabelImage[tempAddress2] != maxLabelN)
						{
							ObjectAreaImage[cameraIndex][tempAddress] = 0;
						}
					}
				}
			}
		}

		int minX, maxX;
		// 채우기 -> 인쇄, 이물 등으로 인해 정제의 내부가 binary로 포함되지 않을 수 있음
		for (y = startY; y < endY; y++)
		{
			minX = MAX_IMAGE_WIDTH;
			maxX = 0;

			for (x = startX; x < endX; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (ObjectAreaImage[cameraIndex][tempAddress])
				{
					if (minX > x) minX = x;
					if (maxX < x) maxX = x;
				}
			}

			for (x = minX; x <= maxX; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;
				ObjectAreaImage[cameraIndex][tempAddress] = 1;
			}
		}

		int beltShiftSize = 32;
		int topEndSW, bottomEndSW;
		memset(TempImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (ObjectAreaImage[cameraIndex][tempAddress])
				{
					topEndSW = bottomEndSW = 0;
					for (r = 4; r <= beltShiftSize; r += 4)
					{
						if (y - r > startY)
						{
							if (!ObjectAreaImage[cameraIndex][tempAddress - r * MAX_IMAGE_WIDTH])
							{
								topEndSW = 1;
								break;
							}
						}
					}

					if (!topEndSW) continue;

					for (r = 4; r <= beltShiftSize; r += 4)
					{
						if (y + r < endY)
						{
							if (!ObjectAreaImage[cameraIndex][tempAddress + r * MAX_IMAGE_WIDTH])
							{
								bottomEndSW = 1;
								break;
							}
						}
					}

					if (topEndSW && bottomEndSW)
					{
						TempImage[tempAddress] = 1;
					}
				}
			}
		}
		// end

		// 벨트예상군 제거
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (TempImage[tempAddress])
				{
					ObjectAreaImage[cameraIndex][tempAddress] = 0;
				}
			}
		}

		// 제거된 영역 중 정제로 예상되는 부분 복원
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (TempImage[tempAddress])
				{
					topEndSW = bottomEndSW = 0;

					for (r = 4; r <= beltShiftSize; r += 4)
					{
						if (y - r > startY)
						{
							if (ObjectAreaImage[cameraIndex][tempAddress - r * MAX_IMAGE_WIDTH])
							{
								TempImage[tempAddress] = 2;
								topEndSW = 1;
								break;
							}
						}
					}

					if (!topEndSW)
					{
						for (r = 4; r <= beltShiftSize; r += 4)
						{
							if (y + r < endY)
							{
								if (ObjectAreaImage[cameraIndex][tempAddress + r * MAX_IMAGE_WIDTH])
								{
									TempImage[tempAddress] = 2;
									break;
								}
							}
						}
					}
				}
			}
		}

		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (TempImage[tempAddress] == 2)
				{
					ObjectAreaImage[cameraIndex][tempAddress] = 1;
				}
			}
		}

		startX = 10;
		endX = MAX_IMAGE_WIDTH - 10;
		startY = 10;
		endY = MAX_IMAGE_HEIGHT - 10;

		for (y = startY; y < endY; y++)
		{
			minX = MAX_IMAGE_WIDTH;
			maxX = 0;

			for (x = startX; x < endX; x += 4)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (ObjectAreaImage[cameraIndex][tempAddress])
				{
					if (minX > x) minX = x;
					if (maxX < x) maxX = x;
				}
			}

			for (x = minX; x <= maxX; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;
				ObjectAreaImage[cameraIndex][tempAddress] = 1;
			}
		}

		int minY, maxY;
		for (x = startX; x < endX; x++)
		{
			minY = MAX_IMAGE_HEIGHT;
			maxY = 0;

			for (y = startY; y < endY; y += 4)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (ObjectAreaImage[cameraIndex][tempAddress])
				{
					if (minY > y) minY = y;
					if (maxY < y) maxY = y;
				}
			}

			for (y = minY; y <= maxY; y++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;
				ObjectAreaImage[cameraIndex][tempAddress] = 1;
			}
		}

		for (y = startY; y < endY; y++)
		{
			ptr = (Byte*)srcImage->Picture->Bitmap->ScanLine[y];
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (ObjectAreaImage[cameraIndex][tempAddress])
				{
					if (ViewOptionCheckBox->Checked == 0)
					{
						if (ObjectAreaImage[cameraIndex][tempAddress - 4] == 0 ||
							ObjectAreaImage[cameraIndex][tempAddress + 4] == 0 ||
							ObjectAreaImage[cameraIndex][tempAddress - 4 * MAX_IMAGE_WIDTH] == 0 ||
							ObjectAreaImage[cameraIndex][tempAddress + 4 * MAX_IMAGE_WIDTH] == 0)
						{
							ptr[3 * x + 0] = 0;
							ptr[3 * x + 1] = 0;
							ptr[3 * x + 2] = 255;
						}
					}
					else
					{
						ptr[3 * x + 0] = ColorSourceImage[tempAddress * 3 + 2];
						ptr[3 * x + 1] = ColorSourceImage[tempAddress * 3 + 1] / 2;
						ptr[3 * x + 2] = ColorSourceImage[tempAddress * 3 + 0];
					}
				}
			}
		}
	}
	else
	{
		// simluation test
		for (y = startY; y < endY; y++)
		{
			ptr = (Byte*)srcImage->Picture->Bitmap->ScanLine[y];
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (x > 320 - 100 && x < 320 + 100 && y > 240 - 50 && y < 240 + 50)
				{
					ObjectAreaImage[cameraIndex][tempAddress] = 1;
				}
			}
		}

		memset(HalfLabelImage, 0, (MAX_IMAGE_WIDTH / 2) * (MAX_IMAGE_HEIGHT / 2) * sizeof(short));
		memset(smallBinaryImage, 0, (MAX_IMAGE_WIDTH / 2) * (MAX_IMAGE_HEIGHT / 2));

		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;
				tempAddress2 = (MAX_IMAGE_WIDTH / 2) * (y / 2) + (x / 2);

				if (ObjectAreaImage[cameraIndex][tempAddress])
				{
					smallBinaryImage[tempAddress2] = 1;
				}
			}
		}

		memset(ObjectAreaImage[cameraIndex], 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		int maxLabelN = LabellingForTabletImage(HalfLabelImage, smallBinaryImage, startX / 2, endX / 2, startY / 2, endY / 2, MAX_IMAGE_WIDTH / 2, MAX_IMAGE_HEIGHT / 2);

		if (maxLabelN)
		{
			for (y = startY; y < endY; y++)
			{
				for (x = startX; x < endX; x++)
				{
					tempAddress = MAX_IMAGE_WIDTH * y + x;
					tempAddress2 = (MAX_IMAGE_WIDTH / 2) * (y / 2) + (x / 2);

					if (HalfLabelImage[tempAddress2] == maxLabelN)
					{
						ObjectAreaImage[cameraIndex][tempAddress] = 1;
					}
				}
			}

			int minX, maxX;
			for (y = startY; y < endY; y++)
			{
				minX = SYSTEM_CAMERA_WIDTH;
				maxX = 0;

				for (x = startX; x < endX; x++)
				{
					tempAddress = y * SYSTEM_CAMERA_WIDTH + x;

					if (ObjectAreaImage[cameraIndex][tempAddress])
					{
						if (minX > x) minX = x;
						if (maxX < x) maxX = x;
					}
				}

				for (x = minX; x <= maxX; x++)
				{
					tempAddress = y * SYSTEM_CAMERA_WIDTH + x;
					ObjectAreaImage[cameraIndex][tempAddress] = 1;
				}
			}
		}

		for (y = startY; y < endY; y++)
		{
			ptr = (Byte*)srcImage->Picture->Bitmap->ScanLine[y];
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (ObjectAreaImage[cameraIndex][tempAddress])
				{
					if (ViewOptionCheckBox->Checked == 0)
					{
						if (ObjectAreaImage[cameraIndex][tempAddress - 4] == 0 ||
							ObjectAreaImage[cameraIndex][tempAddress + 4] == 0 ||
							ObjectAreaImage[cameraIndex][tempAddress - 4 * MAX_IMAGE_WIDTH] == 0 ||
							ObjectAreaImage[cameraIndex][tempAddress + 4 * MAX_IMAGE_WIDTH] == 0)
						{
							ptr[3 * x + 0] = 0;
							ptr[3 * x + 1] = 0;
							ptr[3 * x + 2] = 255;
						}
					}
					else
					{
						ptr[3 * x + 0] = ColorSourceImage[tempAddress * 3 + 2];
						ptr[3 * x + 1] = ColorSourceImage[tempAddress * 3 + 1] / 2;
						ptr[3 * x + 2] = ColorSourceImage[tempAddress * 3 + 0];
					}
				}
			}
		}
	}

	srcImage->Refresh();


	/*
	2020-04-17
	1) 분진이 잔뜩쌓인 상태로 벨트학습을 진행한 후 검사를 시작 -> 기계에서 정제 안착과정에서 분진이 떨어져버림 -> 해당 부분이 레퍼런스보다 어두워지게 될것 -> 정제로 인식하게 될텐데 어떻게 할것인가
	1-1) 우선 검사에 필요한 최저 밝기로 세팅하므로 분진이 지워진다고하더라도 검사에 영향이 있을것 같진 않음
	1-2) 정면은 40기준 밝기면 충분할것 같고, 측면은 사용자가 세팅하니까 괜찮지않겠냐..
	1-3) 정제 안착과정에서 분진이 안떨어져나갈수도있지않냐
	1-4) 일단 이경우에는 벨트를 청소하면 괜찮아지긴하던데..
	*/
}

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

int __fastcall TAutoBrightnessSettingForm::LabellingForTabletImage(short *label_Image, unsigned char *smallSizeBinaryImage, int startX, int endX, int startY, int endY, int imageWidth, int imageHeight)
{
	int i, x, y;
	int temp_address;
	int currentLabel;
	int new_count;
	int newLval;
	int temp;
	int tempAddress;
	int maxLabelN;
	int maxLabelCount;
	int breakSW;

	short CollisionArray[MAX_LABEL_COUNT];
	unsigned short Pixel_N_Of_Label[MAX_LABEL_COUNT];
	short StartX_Label[MAX_LABEL_COUNT];
	short EndX_Label[MAX_LABEL_COUNT];
	short StartY_Label[MAX_LABEL_COUNT];
	short EndY_Label[MAX_LABEL_COUNT];

	currentLabel = 0;

	for (i = 0; i < MAX_LABEL_COUNT; i++)
	{
		CollisionArray[i] = i;
		Pixel_N_Of_Label[i] = 0;
		StartX_Label[i] = 640;
		EndX_Label[i] = 0;
		StartY_Label[i] = 640;
		EndY_Label[i] = 0;
	}

	breakSW = 0;
	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			temp_address = imageWidth * (y)+x;
			if (*(smallSizeBinaryImage + temp_address))
			{
				if (*(label_Image + temp_address - imageWidth) == 0)     // up is background
				{
					if (*(label_Image + temp_address - 1) == 0)       // left is also background
					{
						currentLabel++;
						*(label_Image + temp_address) = currentLabel; // first label number is '1'
					}
					else                        // left is not background
					{
						*(label_Image + temp_address) = *(label_Image + temp_address - 1);
					}
				}
				else                // up is not background
				{
					if (*(label_Image + temp_address - 1) == 0)       // left is background
					{
						*(label_Image + temp_address) = *(label_Image + temp_address - imageWidth);
					}
					else                        // left is not background
					{
						if (*(label_Image + temp_address - imageWidth) == *(label_Image + temp_address - 1))
						{
							*(label_Image + temp_address) = *(label_Image + temp_address - imageWidth);
						}
						else        // collision detected
						{           // Left label이 Up label보다 항상 크다
							CollisionArray[max(*(label_Image + temp_address - 1), *(label_Image + temp_address - imageWidth))] =
								min(*(label_Image + temp_address - 1), *(label_Image + temp_address - imageWidth));
							*(label_Image + temp_address) = CollisionArray[*(label_Image + temp_address - imageWidth)];
						}
					}
				}
				if (currentLabel >= MAX_LABEL_COUNT - 1)
				{
					breakSW = 1;
					break;
				}
			}
		}
		if (breakSW == 1)
			break;
	}

	newLval = 1;
	for (i = 1; i <= currentLabel; i++)
	{
		if (CollisionArray[CollisionArray[i]] > newLval)
		{
			newLval++;
			CollisionArray[i] = newLval;
		}
		else
		{
			CollisionArray[i] = CollisionArray[CollisionArray[i]];
		}
	}

	if (newLval > 500)  newLval = 499;
	new_count = newLval;

	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = imageWidth * (y)+x;
			if (*(smallSizeBinaryImage + tempAddress))
			{
				temp = *(label_Image + tempAddress);
				temp = CollisionArray[temp];
				*(label_Image + tempAddress) = temp;
				Pixel_N_Of_Label[temp]++;
				if (StartX_Label[temp] > x)  StartX_Label[temp] = x;
				if (StartY_Label[temp] > y)  StartY_Label[temp] = y;
				if (EndX_Label[temp] < x)  EndX_Label[temp] = x;
				if (EndY_Label[temp] < y)  EndY_Label[temp] = y;
			}
		}
	}

	maxLabelN = 0;
	maxLabelCount = 0;
	for (i = 1; i <= new_count; i++)
	{
		if (Pixel_N_Of_Label[i] > maxLabelCount)
		{
			maxLabelN = i;
			maxLabelCount = Pixel_N_Of_Label[i];
		}
	}

	return(maxLabelN);
}
//---------------------------------------------------------------------------

void __fastcall TAutoBrightnessSettingForm::CheckTabletBrightness(TTntImage *srcImage, int cameraIndex)
{
	int x, y;
	Byte *ptr;
	int tempAddress, tempAddress2;
	int Value[3];
	int tempCount;

	Value[0] = Value[1] = Value[2] = tempCount = 0;
	if (!SimulationCheckBox->Checked)
	{
		if (!(cameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1 || cameraIndex == SD2_2D_FRONT_FACE_CAMERA_INDEX - 1))
		{
			if (sideCenterPosDataCount[cameraIndex])
			{
				for (int m = 0; m < sideCenterPosDataCount[cameraIndex]; m++)
				{
					x = sideCenterPosData[cameraIndex][m * 2 + 0];
					y = sideCenterPosData[cameraIndex][m * 2 + 1];

					if (x > 10 && x < MAX_IMAGE_WIDTH - 10 && y > 10 && y < MAX_IMAGE_HEIGHT - 10)
					{
						for (int j = y - 2; j <= y + 2; j++)
						{
							ptr = (Byte*)srcImage->Picture->Bitmap->ScanLine[j];
							for (int i = x - 2; i <= x + 2; i++)
							{
								Value[0] += ptr[3 * i + 0];
								Value[1] += ptr[3 * i + 1];
								Value[2] += ptr[3 * i + 2];
								tempCount++;
							}
						}
					}
				}
			}
		}
		else
		{
			for (y = 40; y < MAX_IMAGE_HEIGHT - 40; y++)
			{
				ptr = (Byte*)srcImage->Picture->Bitmap->ScanLine[y];
				for (x = 40; x < MAX_IMAGE_WIDTH - 40; x++)
				{
					tempAddress = MAX_IMAGE_WIDTH * y + x;

					if (ObjectAreaImage[cameraIndex][tempAddress])
					{
						if (ObjectAreaImage[cameraIndex][tempAddress - 20] &&
							ObjectAreaImage[cameraIndex][tempAddress + 20] &&
							ObjectAreaImage[cameraIndex][tempAddress - 20 * MAX_IMAGE_WIDTH] &&
							ObjectAreaImage[cameraIndex][tempAddress + 20 * MAX_IMAGE_WIDTH])
						{
							Value[0] += ptr[3 * x + 0];
							Value[1] += ptr[3 * x + 1];
							Value[2] += ptr[3 * x + 2];
							tempCount++;
						}
					}
				}
			}
		}
	}
	else
	{
		for (y = 40; y < MAX_IMAGE_HEIGHT - 40; y++)
		{
			ptr = (Byte*)srcImage->Picture->Bitmap->ScanLine[y];
			for (x = 40; x < MAX_IMAGE_WIDTH - 40; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (ObjectAreaImage[cameraIndex][tempAddress])
				{
					if (ObjectAreaImage[cameraIndex][tempAddress - 20] &&
						ObjectAreaImage[cameraIndex][tempAddress + 20] &&
						ObjectAreaImage[cameraIndex][tempAddress - 20 * MAX_IMAGE_WIDTH] &&
						ObjectAreaImage[cameraIndex][tempAddress + 20 * MAX_IMAGE_WIDTH])
					{
						Value[0] += ptr[3 * x + 0];
						Value[1] += ptr[3 * x + 1];
						Value[2] += ptr[3 * x + 2];
						tempCount++;
					}
				}
			}
		}
	}

	for (y = 40; y < MAX_IMAGE_HEIGHT - 40; y++)
	{
		ptr = (Byte*)srcImage->Picture->Bitmap->ScanLine[y];
		for (x = 40; x < MAX_IMAGE_WIDTH - 40; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;

			if (ObjectAreaImage[cameraIndex][tempAddress])
			{
				if (ObjectAreaImage[cameraIndex][tempAddress - 4] == 0 ||
					ObjectAreaImage[cameraIndex][tempAddress + 4] == 0 ||
					ObjectAreaImage[cameraIndex][tempAddress - 4 * MAX_IMAGE_WIDTH] == 0 ||
					ObjectAreaImage[cameraIndex][tempAddress + 4 * MAX_IMAGE_WIDTH] == 0)
				{
					ptr[3 * x + 0] = 0;
					ptr[3 * x + 1] = 0;
					ptr[3 * x + 2] = 255;
				}
			}
		}
	}

	if (sideCenterPosDataCount[cameraIndex])
	{
		for (int m = 0; m < sideCenterPosDataCount[cameraIndex]; m++)
		{
			x = sideCenterPosData[cameraIndex][m * 2 + 0];
			y = sideCenterPosData[cameraIndex][m * 2 + 1];

			if (x > 10 && x < MAX_IMAGE_WIDTH - 10 && y > 10 && y < MAX_IMAGE_HEIGHT - 10)
			{
				for (int j = y - 2; j <= y + 2; j++)
				{
					ptr = (Byte*)srcImage->Picture->Bitmap->ScanLine[j];
					for (int i = x - 2; i <= x + 2; i++)
					{
						int tempRGB[3];
						tempRGB[0] = ptr[3 * i + 0];
						tempRGB[1] = ptr[3 * i + 1];
						tempRGB[2] = ptr[3 * i + 2];

						ptr[3 * i + 0] = 255 - tempRGB[0];
						ptr[3 * i + 1] = 255 - tempRGB[1];
						ptr[3 * i + 2] = 255 - tempRGB[2];
					}
				}
			}
		}
	}

	TTntPanel *CameraBrightnessValuePanel = (TTntPanel *)FindComponent("CameraBrightnessValuePanel" + IntToStr(cameraIndex + 1));

	int colorDiff = 256;

	int mainCameraIndex;
	if (cameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1 || cameraIndex == SD2_2D_FRONT_FACE_CAMERA_INDEX - 1)
	{
		mainCameraIndex = ActiveVerticalCameraIndex - 1;
	}
	else
	{
		mainCameraIndex = ActiveSideCameraIndex - 1;
	}

	if (CameraBrightnessValuePanel)
	{
		if (tempCount)
		{
      checkedSW[cameraIndex] = true;

			Value[0] /= tempCount;
			Value[1] /= tempCount;
			Value[2] /= tempCount;

			int maxValue = max(Value[0], max(Value[1], Value[2]));

			CameraBrightnessValuePanel->Caption = IntToStr(maxValue);

			int standardValue;
			if (processingStep == PROCESSING_STEP_SET_MAIN_CAMERA_BRIGHTNESS)
			{
				standardValue = StrToInt(TabletDefaultBrighnessPanel->Caption);
			}
			else
			{
				standardValue = CameraBrightness[mainCameraIndex];
			}

			colorDiff = abs(standardValue - maxValue);

			if (MinBrightnessLevel[cameraIndex] > colorDiff)
			{
				MinBrightnessLevel[cameraIndex] = colorDiff;

				CameraBrightness[cameraIndex] = maxValue;
				StudyShutterSpeed[cameraIndex] = currentShutterSpeed[cameraIndex];
				StudyDigitalGain[cameraIndex] = currentDigitalGain[cameraIndex];
			}

			if (!SimulationCheckBox->Checked)
			{
				if (processingStep == PROCESSING_STEP_SET_MAIN_CAMERA_BRIGHTNESS)
				{
					if (MinBrightnessLevel[cameraIndex] <= MAIN_PERMISSIBLE_DIFF_RANGE)
					{
						brightnessStudyCompleted[cameraIndex] = CAMERA_BRIGHTNESS_CHECK_COMPLETED;
					}
					else if (fstStep[cameraIndex])
					{
						fstStep[cameraIndex] = false;

						if (standardValue < maxValue)
						{
							brightnessStudyCompleted[cameraIndex] = CAMERA_BRIGHTNESS_CHECK_COMPLETED;
						}
					}
				}
				else
				{
					if (MinBrightnessLevel[cameraIndex] <= SUB_PERMISSIBLE_DIFF_RANGE)
					{
						brightnessStudyCompleted[cameraIndex] = CAMERA_BRIGHTNESS_CHECK_COMPLETED;
					}

					// 현재밝기가 기준치보다 높은경우 에러카운트 증가
					colorDiff = maxValue - standardValue;
					if (colorDiff > SUB_PERMISSIBLE_DIFF_RANGE)
					{
						continuousBrightnessOverCount[cameraIndex]++;
					}
					else
					{
						continuousBrightnessOverCount[cameraIndex] = 0;
					}

					if (continuousBrightnessOverCount[cameraIndex] > 5)
					{
						brightnessStudyCompleted[cameraIndex] = CAMERA_BRIGHTNESS_CHECK_COMPLETED;
					}
				}
			}
			else
			{
				brightnessStudyCompleted[cameraIndex] = CAMERA_BRIGHTNESS_CHECK_COMPLETED;
			}
		}
		else
		{
			CameraBrightnessValuePanel->Caption = "N/A";
		}
	}

	if (brightnessStudyCompleted[cameraIndex] == CAMERA_BRIGHTNESS_CHECK_NONE)
	{
		if (processingStep == PROCESSING_STEP_SET_MAIN_CAMERA_BRIGHTNESS)
		{
			currentShutterSpeed[cameraIndex] += MAIN_SHUTTER_SPEED_INCRESEMENT;
			if (currentShutterSpeed[cameraIndex] >= MAX_SHUTTER_SPEED && currentDigitalGain[cameraIndex] < MAX_DIGITAL_GAIN)
			{
				currentShutterSpeed[cameraIndex] = MAIN_MIN_SHUTTER_SPEED;
				currentDigitalGain[cameraIndex]++;
			}
			else if (currentShutterSpeed[cameraIndex] >= MAX_SHUTTER_SPEED && currentDigitalGain[cameraIndex] == MAX_DIGITAL_GAIN)
			{
				currentShutterSpeed[cameraIndex] = MAIN_MIN_SHUTTER_SPEED;
				currentDigitalGain[cameraIndex] = MIN_DIGITAL_GAIN;

				brightnessStudyCompleted[cameraIndex] = CAMERA_BRIGHTNESS_CHECK_FAILED;
			}
		}
		else
		{
			currentShutterSpeed[cameraIndex] += SUB_SHUTTER_SPEED_INCRESEMENT;
			if (currentShutterSpeed[cameraIndex] >= MAX_SHUTTER_SPEED)
			{
				currentShutterSpeed[cameraIndex] = SUB_MIN_SHUTTER_SPEED;
				brightnessStudyCompleted[cameraIndex] = CAMERA_BRIGHTNESS_CHECK_COMPLETED;
			}
		}
	}
	else if (brightnessStudyCompleted[cameraIndex] == CAMERA_BRIGHTNESS_CHECK_COMPLETED)
	{
		currentShutterSpeed[cameraIndex] = StudyShutterSpeed[cameraIndex];
		currentDigitalGain[cameraIndex] = StudyDigitalGain[cameraIndex];
	}
}

//---------------------------------------------------------------------------
void __fastcall TAutoBrightnessSettingForm::ViewTabletBrightness(TTntImage *srcImage, int cameraIndex)
{
	int x, y;
	Byte *ptr;
	int tempAddress, tempAddress2;
	int Value[3];
	int tempCount;

	Value[0] = Value[1] = Value[2] = tempCount = 0;
	if (!SimulationCheckBox->Checked)
	{
		if (!(cameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1 || cameraIndex == SD2_2D_FRONT_FACE_CAMERA_INDEX - 1))
		{
			if (sideCenterPosDataCount[cameraIndex])
			{
				for (int m = 0; m < sideCenterPosDataCount[cameraIndex]; m++)
				{
					x = sideCenterPosData[cameraIndex][m * 2 + 0];
					y = sideCenterPosData[cameraIndex][m * 2 + 1];

					if (x > 10 && x < MAX_IMAGE_WIDTH - 10 && y > 10 && y < MAX_IMAGE_HEIGHT - 10)
					{
						for (int j = y - 2; j <= y + 2; j++)
						{
							ptr = (Byte*)srcImage->Picture->Bitmap->ScanLine[j];
							for (int i = x - 2; i <= x + 2; i++)
							{
								Value[0] += ptr[3 * i + 0];
								Value[1] += ptr[3 * i + 1];
								Value[2] += ptr[3 * i + 2];
								tempCount++;
							}
						}
					}
				}
			}
		}
		else
		{
			for (y = 40; y < MAX_IMAGE_HEIGHT - 40; y++)
			{
				ptr = (Byte*)srcImage->Picture->Bitmap->ScanLine[y];
				for (x = 40; x < MAX_IMAGE_WIDTH - 40; x++)
				{
					tempAddress = MAX_IMAGE_WIDTH * y + x;

					if (ObjectAreaImage[cameraIndex][tempAddress])
					{
						if (ObjectAreaImage[cameraIndex][tempAddress - 20] &&
							ObjectAreaImage[cameraIndex][tempAddress + 20] &&
							ObjectAreaImage[cameraIndex][tempAddress - 20 * MAX_IMAGE_WIDTH] &&
							ObjectAreaImage[cameraIndex][tempAddress + 20 * MAX_IMAGE_WIDTH])
						{
							Value[0] += ptr[3 * x + 0];
							Value[1] += ptr[3 * x + 1];
							Value[2] += ptr[3 * x + 2];
							tempCount++;
						}
					}
				}
			}
		}
	}
	else
	{
		for (y = 40; y < MAX_IMAGE_HEIGHT - 40; y++)
		{
			ptr = (Byte*)srcImage->Picture->Bitmap->ScanLine[y];
			for (x = 40; x < MAX_IMAGE_WIDTH - 40; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (ObjectAreaImage[cameraIndex][tempAddress])
				{
					if (ObjectAreaImage[cameraIndex][tempAddress - 20] &&
						ObjectAreaImage[cameraIndex][tempAddress + 20] &&
						ObjectAreaImage[cameraIndex][tempAddress - 20 * MAX_IMAGE_WIDTH] &&
						ObjectAreaImage[cameraIndex][tempAddress + 20 * MAX_IMAGE_WIDTH])
					{
						Value[0] += ptr[3 * x + 0];
						Value[1] += ptr[3 * x + 1];
						Value[2] += ptr[3 * x + 2];
						tempCount++;
					}
				}
			}
		}
	}

	for (y = 40; y < MAX_IMAGE_HEIGHT - 40; y++)
	{
		ptr = (Byte*)srcImage->Picture->Bitmap->ScanLine[y];
		for (x = 40; x < MAX_IMAGE_WIDTH - 40; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;

			if (ObjectAreaImage[cameraIndex][tempAddress])
			{
				if (ObjectAreaImage[cameraIndex][tempAddress - 4] == 0 ||
					ObjectAreaImage[cameraIndex][tempAddress + 4] == 0 ||
					ObjectAreaImage[cameraIndex][tempAddress - 4 * MAX_IMAGE_WIDTH] == 0 ||
					ObjectAreaImage[cameraIndex][tempAddress + 4 * MAX_IMAGE_WIDTH] == 0)
				{
					ptr[3 * x + 0] = 0;
					ptr[3 * x + 1] = 0;
					ptr[3 * x + 2] = 255;
				}
			}
		}
	}

	if (sideCenterPosDataCount[cameraIndex])
	{
		for (int m = 0; m < sideCenterPosDataCount[cameraIndex]; m++)
		{
			x = sideCenterPosData[cameraIndex][m * 2 + 0];
			y = sideCenterPosData[cameraIndex][m * 2 + 1];

			if (x > 10 && x < MAX_IMAGE_WIDTH - 10 && y > 10 && y < MAX_IMAGE_HEIGHT - 10)
			{
				for (int j = y - 2; j <= y + 2; j++)
				{
					ptr = (Byte*)srcImage->Picture->Bitmap->ScanLine[j];
					for (int i = x - 2; i <= x + 2; i++)
					{
						int tempRGB[3];
						tempRGB[0] = ptr[3 * i + 0];
						tempRGB[1] = ptr[3 * i + 1];
						tempRGB[2] = ptr[3 * i + 2];

						ptr[3 * i + 0] = 255 - tempRGB[0];
						ptr[3 * i + 1] = 255 - tempRGB[1];
						ptr[3 * i + 2] = 255 - tempRGB[2];
					}
				}
			}
		}
	}

	TTntPanel *CameraBrightnessValuePanel = (TTntPanel *)FindComponent("CameraBrightnessValuePanel" + IntToStr(cameraIndex + 1));

	int colorDiff = 256;

	if (CameraBrightnessValuePanel)
	{
		if (tempCount)
		{
			Value[0] /= tempCount;
			Value[1] /= tempCount;
			Value[2] /= tempCount;

			int maxValue = max(Value[0], max(Value[1], Value[2]));

			CameraBrightnessValuePanel->Caption = IntToStr(maxValue);
		}
		else
		{
			CameraBrightnessValuePanel->Caption = "N/A";
		}
	}
}

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

void __fastcall TAutoBrightnessSettingForm::SetBrightnessCheckingResult()
{
	for (int cameraIndex = 1; cameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
	{
		TTntPanel *CameraStatusPanel = (TTntPanel *)FindComponent("CameraStatusPanel" + IntToStr(cameraIndex));
		TTntPanel *CameraBrightnessLevelPanel = (TTntPanel *)FindComponent("CameraBrightnessLevelPanel" + IntToStr(cameraIndex));
		TTntPanel *CameraShutterSpeedPanel = (TTntPanel *)FindComponent("CameraShutterSpeedPanel" + IntToStr(cameraIndex));
		TTntPanel *CameraGainPanel = (TTntPanel *)FindComponent("CameraGainPanel" + IntToStr(cameraIndex));

		if (CameraStatusPanel)
		{
			if (brightnessStudyCompleted[cameraIndex - 1] == CAMERA_BRIGHTNESS_CHECK_COMPLETED)
			{
				CameraStatusPanel->Caption = "O";
			}
		}

		if (CameraBrightnessLevelPanel)
		{
			if (brightnessStudyCompleted[cameraIndex - 1] == CAMERA_BRIGHTNESS_CHECK_COMPLETED)
			{
				CameraBrightnessLevelPanel->Caption = IntToStr(CameraBrightness[cameraIndex - 1]);
			}
		}

		if (CameraShutterSpeedPanel)
		{
			if (brightnessStudyCompleted[cameraIndex - 1] == CAMERA_BRIGHTNESS_CHECK_COMPLETED)
			{
				CameraShutterSpeedPanel->Caption = IntToStr(StudyShutterSpeed[cameraIndex - 1]);
			}
		}

		if (CameraGainPanel)
		{
			if (brightnessStudyCompleted[cameraIndex - 1] == CAMERA_BRIGHTNESS_CHECK_COMPLETED)
			{
				CameraGainPanel->Caption = IntToStr(StudyDigitalGain[cameraIndex - 1]);
			}
		}
	}
}

//---------------------------------------------------------------------------
void __fastcall TAutoBrightnessSettingForm::HelpPanelDblClick(
	TObject *Sender)
{
	SimulationCheckBox->Visible = !SimulationCheckBox->Visible;
	SaveBmpCheckBox->Visible = !SaveBmpCheckBox->Visible;
	Label11->Visible = !Label11->Visible;
	ImageRootEdit->Visible = !ImageRootEdit->Visible;
	BitBtn1->Visible = !BitBtn1->Visible;
	TntUpDown2->Visible = !TntUpDown2->Visible;
	ViewOptionCheckBox->Visible = !ViewOptionCheckBox->Visible;
}
//---------------------------------------------------------------------------

void __fastcall TAutoBrightnessSettingForm::BitBtn1Click(TObject *Sender)
{
	AnsiString ImagePath = ImageRootEdit->Text;

	bool bError = false;
	if (!DirectoryExists(ImagePath))
	{
		ShowMessage("fail");
		bError = true;
	}

	ImagePath += "\\Background";

	if (!DirectoryExists(ImagePath))
	{
		ShowMessage("fail");
		bError = true;
	}


	if (!bError)
	{
		AnsiString filename;

		Graphics::TBitmap *img1;
		img1 = new Graphics::TBitmap();

		memset(BackgroundImage, 0, SYSTEM_TOTAL_CAMERA_COUNT * MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * 3 * sizeof(int));
		memset(stdCount, 0, sizeof(int) * SYSTEM_TOTAL_CAMERA_COUNT);

		for (int imageIndex = 1; imageIndex <= 100; imageIndex++)
		{
			for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
			{
				if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_DISCONNECT &&
					CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D && SystemLinkCameraInfo[globalCameraIndex] != 0)
				{
					filename = ImagePath + "\\Image" + IntToStr(imageIndex) + "_C" + IntToStr(globalCameraIndex + 1) + ".bmp";

					if (FileExists(filename))
					{
						img1->LoadFromFile(filename);

						int x, y;
						Byte *ptr;
						int tempAddress;

						for (y = 0; y < MAX_IMAGE_HEIGHT; y++)
						{
							ptr = (Byte*)img1->ScanLine[y];
							for (x = 0; x < MAX_IMAGE_WIDTH; x++)
							{
								tempAddress = MAX_IMAGE_WIDTH * y + x;

								BackgroundImage[globalCameraIndex][tempAddress * 3 + 0] += ptr[3 * x + 0];
								BackgroundImage[globalCameraIndex][tempAddress * 3 + 1] += ptr[3 * x + 1];
								BackgroundImage[globalCameraIndex][tempAddress * 3 + 2] += ptr[3 * x + 2];
							}
						}

						stdCount[globalCameraIndex]++;

						TImage *tempImage = (TImage *)FindComponent("CameraImage" + IntToStr(globalCameraIndex + 1));

						if (tempImage)
						{
							tempImage->Picture->Bitmap->Assign(img1);
							tempImage->Refresh();
						}
					}
				}

				Application->ProcessMessages();
			}
		}

		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
			if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_DISCONNECT &&
				CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D && SystemLinkCameraInfo[globalCameraIndex] != 0)
			{
				if (stdCount[globalCameraIndex])
				{
					int x, y;
					Byte *ptr;
					int tempAddress;

					for (y = 0; y < MAX_IMAGE_HEIGHT; y++)
					{
						ptr = (Byte*)img1->ScanLine[y];
						for (x = 0; x < MAX_IMAGE_WIDTH; x++)
						{
							tempAddress = MAX_IMAGE_WIDTH * y + x;

							BackgroundImage[globalCameraIndex][tempAddress * 3 + 0] /= stdCount[globalCameraIndex];
							BackgroundImage[globalCameraIndex][tempAddress * 3 + 1] /= stdCount[globalCameraIndex];
							BackgroundImage[globalCameraIndex][tempAddress * 3 + 2] /= stdCount[globalCameraIndex];

							ptr[3 * x + 0] = BackgroundImage[globalCameraIndex][tempAddress * 3 + 0];
							ptr[3 * x + 1] = BackgroundImage[globalCameraIndex][tempAddress * 3 + 1];
							ptr[3 * x + 2] = BackgroundImage[globalCameraIndex][tempAddress * 3 + 2];
						}
					}
				}

				TImage *tempImage = (TImage *)FindComponent("CameraImage" + IntToStr(globalCameraIndex + 1));

				if (tempImage)
				{
					tempImage->Picture->Bitmap->Assign(img1);
					tempImage->Refresh();
				}
			}

			Application->ProcessMessages();
		}

		delete img1;
	}
}
//---------------------------------------------------------------------------

void __fastcall TAutoBrightnessSettingForm::TntUpDown2Click(
	TObject *Sender, TUDBtnType Button)
{
	AnsiString ImagePath = ImageRootEdit->Text;

	bool bError = false;
	if (!DirectoryExists(ImagePath))
	{
		ShowMessage("fail");
		bError = true;
	}

	/*
	ImagePath += "\\Background";

	if (!DirectoryExists(ImagePath))
	{
	ShowMessage("fail");
	bError = true;
	}
	*/

	ImagePath += "\\Object";

	if (!DirectoryExists(ImagePath))
	{
		ShowMessage("fail");
		bError = true;
	}

	int existDataCameraCount = 0;
	for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	{
		if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_DISCONNECT &&
			CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D && SystemLinkCameraInfo[globalCameraIndex] != 0)
		{
			if (stdCount[globalCameraIndex])
			{
				existDataCameraCount++;
			}
		}
	}

	if (existDataCameraCount == 0)
	{
		bError = true;
	}

	memset(objStartNum, 0, sizeof(int) * SYSTEM_TOTAL_CAMERA_COUNT);
	memset(objEndNum, 0, sizeof(int) * SYSTEM_TOTAL_CAMERA_COUNT);

	AnsiString filename;

	for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	{
		if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_DISCONNECT &&
			CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D && SystemLinkCameraInfo[globalCameraIndex] != 0)
		{
			if (stdCount[globalCameraIndex])
			{
				int minN = 10000;
				int maxN = 0;

				for (int imageIndex = 1; imageIndex <= 100; imageIndex++)
				{
					filename = ImagePath + "\\Image" + IntToStr(imageIndex) + "_C" + IntToStr(globalCameraIndex + 1) + ".bmp";

					if (FileExists(filename))
					{
						if (minN >= imageIndex)
						{
							minN = imageIndex;
						}

						if (maxN <= imageIndex)
						{
							maxN = imageIndex;
						}
					}
				}

				objStartNum[globalCameraIndex] = minN;
				objEndNum[globalCameraIndex] = maxN;
			}
		}
	}

	if (!bError)
	{
		int imagePos = TntUpDown2->Position;

		Graphics::TBitmap *img1;
		img1 = new Graphics::TBitmap();

		unsigned char *objectAreaImage = new unsigned char[MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT];

		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
			if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_DISCONNECT &&
				CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D && SystemLinkCameraInfo[globalCameraIndex] != 0)
			{
				if (stdCount[globalCameraIndex])
				{
					int imageIndex = objStartNum[globalCameraIndex] + (imagePos - 1);

					filename = ImagePath + "\\Image" + IntToStr(imageIndex) + "_C" + IntToStr(globalCameraIndex + 1) + ".bmp";

					if (FileExists(filename))
					{
						memset(ColorSourceImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * 3);
						memset(objectAreaImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
						img1->LoadFromFile(filename);

						TTntImage *DestImage;
						DestImage = (TTntImage *)FindComponent("CameraImage" + IntToStr(globalCameraIndex + 1));
						DestImage->Picture->Bitmap->Assign(img1);

						if (globalCameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1 || globalCameraIndex == SD2_2D_FRONT_FACE_CAMERA_INDEX - 1)
						{
							SetFrontFaceObjectArea(DestImage, globalCameraIndex);
						}
						else
						{
							SetSideFaceObjectArea(DestImage, globalCameraIndex);
						}
					}
				}
			}
		}

		delete img1;
	}
}
//---------------------------------------------------------------------------

void __fastcall TAutoBrightnessSettingForm::SetSideFaceObjectArea(TTntImage *srcImage, int cameraIndex)
{
	memset(ObjectAreaImage[cameraIndex], 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
	sideCenterPosDataCount[cameraIndex] = 0;

	int x, y;
	int tempAddress, tempAddress2;
	int startX, endX, startY, endY;
	unsigned char *maxRGBFactorSrcArry;
	unsigned char *maxRGBFactorOstArry;
	int rgb;
	int maxRGBCount[3];
	int maxValue;
	int RGBValue[3];
	int colorDiff[3];
	int maxRGBFactor;
	int beltShiftSize;
	int tempX, tempY;
	int searchingCount;
	int topEndSW, bottomEndSW;
	int r;
	int binSW;
	int colorRate[3];
	int colorRateDiff[3];
	int tempCount;
	int colorSum;
	int ostColorRate;
	int srcColorRate;
	int avgTabletColorRate;
	unsigned char smallBinaryImage[(MAX_IMAGE_WIDTH / 2) * (MAX_IMAGE_HEIGHT / 2)];
	short halfLabelImage[(MAX_IMAGE_WIDTH / 2) * (MAX_IMAGE_HEIGHT / 2)];
	int maxLabelN;
	int minX, maxX;
	int minY, maxY;
	int mostRGB;
	int diff;
	int validBinCount;
	int value;
	int leftSW, rightSW, bottomSW, topSW;
	int chromaticThreshold;
	int noiseCount;
	int threshold;
	unsigned char *tempBinaryImage;
	int areaHeight;
	int ROIWidth;
	int ROIHeight;
	int left, right, top, bottom;
	int gradX, gradY;
	int upSW1, upSW2;
	int downSW1, downSW2;
	int option;
	int maxHeight;
	int heightCheckSW;
	int ClosedAreaSize;
	int tempSum;
	int avgColorValue;
	int bottomCenterY;
	int realTabletThreshold;
	int centerPassCount;
	int tempCenterPassCount;
	int shift;
	unsigned char *expectedTopLineGrdImage;
	Byte *ptr;
	int trdRGBFactor;
	int minValue;

	if (!SimulationCheckBox->Checked)
	{
		startX = 10;
		endX = MAX_IMAGE_WIDTH - 10;
		startY = 10;
		endY = MAX_IMAGE_HEIGHT - 10;

		maxRGBFactorSrcArry = DentedArea;
		maxRGBFactorOstArry = ThreeD_Image;
		expectedTopLineGrdImage = PlanariztionThreeDEdgeImage;

		memset(halfLabelImage, 0, (MAX_IMAGE_WIDTH / 2) * (MAX_IMAGE_HEIGHT / 2) * sizeof(short));
		memset(smallBinaryImage, 0, (MAX_IMAGE_WIDTH / 2) * (MAX_IMAGE_HEIGHT / 2));
		memset(ShapeBinaryImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		memset(maxRGBFactorSrcArry, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		memset(maxRGBFactorOstArry, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		memset(ColorRateImageSrcArr, 0, sizeof(short) * MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * 3);
		memset(ColorRateImageOstArr, 0, sizeof(short) * MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * 3);

		maxRGBFactor = 1;
		threshold = 40;

		memset(ColorSourceImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * 3);

		for (y = startY; y < endY; y++)
		{
			ptr = (Byte*)srcImage->Picture->Bitmap->ScanLine[y];
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				ColorSourceImage[tempAddress * 3 + 0] = ptr[3 * x + 0];
				ColorSourceImage[tempAddress * 3 + 1] = ptr[3 * x + 1];
				ColorSourceImage[tempAddress * 3 + 2] = ptr[3 * x + 2];
			}
		}

		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (ColorSourceImage[tempAddress * 3 + 0] > threshold ||
					ColorSourceImage[tempAddress * 3 + 1] > threshold ||
					ColorSourceImage[tempAddress * 3 + 2] > threshold)
				{
					colorDiff[0] = ColorSourceImage[tempAddress * 3 + 0] - BackgroundImage[cameraIndex][tempAddress * 3 + 0];
					colorDiff[1] = ColorSourceImage[tempAddress * 3 + 1] - BackgroundImage[cameraIndex][tempAddress * 3 + 1];
					colorDiff[2] = ColorSourceImage[tempAddress * 3 + 2] - BackgroundImage[cameraIndex][tempAddress * 3 + 2];

					if (abs(colorDiff[0]) > threshold ||
						abs(colorDiff[1]) > threshold ||
						abs(colorDiff[2]) > threshold)
					{
						ShapeBinaryImage[tempAddress] = 2;
					}
					else if (abs(colorDiff[0]) > MIN_OBJECT_COLOR_DIFF ||
						abs(colorDiff[1]) > MIN_OBJECT_COLOR_DIFF ||
						abs(colorDiff[2]) > MIN_OBJECT_COLOR_DIFF)
					{
						ShapeBinaryImage[tempAddress] = 1;
					}
				}
			}
		}

		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				RGBValue[0] = ColorSourceImage[tempAddress * 3 + 0];
				RGBValue[1] = ColorSourceImage[tempAddress * 3 + 1];
				RGBValue[2] = ColorSourceImage[tempAddress * 3 + 2];

				maxValue = max(RGBValue[0], max(RGBValue[1], RGBValue[2]));

				if (maxValue == RGBValue[0])
				{
					maxRGBFactorSrcArry[tempAddress] = 1;

					minValue = min(RGBValue[1], RGBValue[2]);
					if (minValue == RGBValue[1])
					{
						maxRGBFactorSrcArry[tempAddress] |= (2 << 4);
					}
					else if (minValue == RGBValue[2])
					{
						maxRGBFactorSrcArry[tempAddress] |= (3 << 4);
					}
				}
				else if (maxValue == RGBValue[1])
				{
					maxRGBFactorSrcArry[tempAddress] = 2;

					minValue = min(RGBValue[0], RGBValue[2]);
					if (minValue == RGBValue[0])
					{
						maxRGBFactorSrcArry[tempAddress] |= (1 << 4);
					}
					else if (minValue == RGBValue[2])
					{
						maxRGBFactorSrcArry[tempAddress] |= (3 << 4);
					}
				}
				else if (maxValue == RGBValue[2])
				{
					maxRGBFactorSrcArry[tempAddress] = 3;

					minValue = min(RGBValue[0], RGBValue[1]);
					if (minValue == RGBValue[0])
					{
						maxRGBFactorSrcArry[tempAddress] |= (1 << 4);
					}
					else if (minValue == RGBValue[1])
					{
						maxRGBFactorSrcArry[tempAddress] |= (2 << 4);
					}
				}

				colorSum = RGBValue[0] + RGBValue[1] + RGBValue[2];
				if (colorSum)
				{
					ColorRateImageSrcArr[tempAddress * 3 + 0] = RGBValue[0] * 1000 / colorSum;
					ColorRateImageSrcArr[tempAddress * 3 + 1] = RGBValue[1] * 1000 / colorSum;
					ColorRateImageSrcArr[tempAddress * 3 + 2] = RGBValue[2] * 1000 / colorSum;
				}

				RGBValue[0] = BackgroundImage[cameraIndex][tempAddress * 3 + 0];
				RGBValue[1] = BackgroundImage[cameraIndex][tempAddress * 3 + 1];
				RGBValue[2] = BackgroundImage[cameraIndex][tempAddress * 3 + 2];

				maxValue = max(RGBValue[0], max(RGBValue[1], RGBValue[2]));

				if (maxValue == RGBValue[0])
				{
					maxRGBFactorOstArry[tempAddress] = 1;

					minValue = min(RGBValue[1], RGBValue[2]);
					if (minValue == RGBValue[1])
					{
						maxRGBFactorOstArry[tempAddress] |= (2 << 4);
					}
					else if (minValue == RGBValue[2])
					{
						maxRGBFactorOstArry[tempAddress] |= (3 << 4);
					}
				}
				else if (maxValue == RGBValue[1])
				{
					maxRGBFactorOstArry[tempAddress] = 2;

					minValue = min(RGBValue[0], RGBValue[2]);
					if (minValue == RGBValue[0])
					{
						maxRGBFactorOstArry[tempAddress] |= (1 << 4);
					}
					else if (minValue == RGBValue[2])
					{
						maxRGBFactorOstArry[tempAddress] |= (3 << 4);
					}
				}
				else if (maxValue == RGBValue[2])
				{
					maxRGBFactorOstArry[tempAddress] = 3;

					minValue = min(RGBValue[0], RGBValue[1]);
					if (minValue == RGBValue[0])
					{
						maxRGBFactorOstArry[tempAddress] |= (1 << 4);
					}
					else if (minValue == RGBValue[1])
					{
						maxRGBFactorOstArry[tempAddress] |= (2 << 4);
					}
				}

				colorSum = RGBValue[0] + RGBValue[1] + RGBValue[2];
				if (colorSum)
				{
					ColorRateImageOstArr[tempAddress * 3 + 0] = RGBValue[0] * 1000 / colorSum;
					ColorRateImageOstArr[tempAddress * 3 + 1] = RGBValue[1] * 1000 / colorSum;
					ColorRateImageOstArr[tempAddress * 3 + 2] = RGBValue[2] * 1000 / colorSum;
				}
			}
		}

		memcpy(TempImage, ShapeBinaryImage, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (TempImage[tempAddress] == 1)
				{
					if ((maxRGBFactorSrcArry[tempAddress] & 0x0F) != (maxRGBFactorOstArry[tempAddress] & 0x0F))
					{
						searchingCount = validBinCount = 0;
						for (r = 12; r >= 4; r -= 4)
						{
							if (x - r > startX)
							{
								searchingCount++;
								tempAddress2 = tempAddress - r;
								if ((maxRGBFactorSrcArry[tempAddress] & 0x0F) != (maxRGBFactorOstArry[tempAddress2] & 0x0F))
								{
									validBinCount++;
								}
							}

							if (x + r < endX)
							{
								searchingCount++;
								tempAddress2 = tempAddress + r;
								if ((maxRGBFactorSrcArry[tempAddress] & 0x0F) != (maxRGBFactorOstArry[tempAddress2] & 0x0F))
								{
									validBinCount++;
								}
							}

							if (y - r > startY)
							{
								searchingCount++;
								tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH;
								if ((maxRGBFactorSrcArry[tempAddress] & 0x0F) != (maxRGBFactorOstArry[tempAddress2] & 0x0F))
								{
									validBinCount++;
								}
							}

							if (y + r < endY)
							{
								searchingCount++;
								tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH;
								if ((maxRGBFactorSrcArry[tempAddress] & 0x0F) != (maxRGBFactorOstArry[tempAddress2] & 0x0F))
								{
									validBinCount++;
								}
							}

							if (x - r > startX && y - r > startY)
							{
								searchingCount++;
								tempAddress2 = tempAddress - r - r * MAX_IMAGE_WIDTH;
								if ((maxRGBFactorSrcArry[tempAddress] & 0x0F) != (maxRGBFactorOstArry[tempAddress2] & 0x0F))
								{
									validBinCount++;
								}
							}

							if (x - r > startX && y - r < endY)
							{
								searchingCount++;
								tempAddress2 = tempAddress - r + r * MAX_IMAGE_WIDTH;
								if ((maxRGBFactorSrcArry[tempAddress] & 0x0F) != (maxRGBFactorOstArry[tempAddress2] & 0x0F))
								{
									validBinCount++;
								}
							}

							if (x + r < endX && y - r > startY)
							{
								searchingCount++;
								tempAddress2 = tempAddress + r - r * MAX_IMAGE_WIDTH;
								if ((maxRGBFactorSrcArry[tempAddress] & 0x0F) != (maxRGBFactorOstArry[tempAddress2] & 0x0F))
								{
									validBinCount++;
								}
							}

							if (x + r < endX && y - r < endY)
							{
								searchingCount++;
								tempAddress2 = tempAddress + r + r * MAX_IMAGE_WIDTH;
								if ((maxRGBFactorSrcArry[tempAddress] & 0x0F) != (maxRGBFactorOstArry[tempAddress2] & 0x0F))
								{
									validBinCount++;
								}
							}
						}

						if (searchingCount)
						{
							if (searchingCount * 4 / 5 < validBinCount)
							{
								ShapeBinaryImage[tempAddress] = 2;
							}
						}
					}
					else
					{
						mostRGB = (maxRGBFactorSrcArry[tempAddress] & 0x0F) - 1;
						colorDiff[mostRGB] = abs(ColorRateImageSrcArr[tempAddress * 3 + mostRGB] - ColorRateImageOstArr[tempAddress * 3 + mostRGB]);

						if (colorDiff[mostRGB] > 50)
						{
							ShapeBinaryImage[tempAddress] = 2;
						}
						else
						{
							colorDiff[0] = ColorSourceImage[tempAddress * 3 + 0] - BackgroundImage[cameraIndex][tempAddress * 3 + 0];
							colorDiff[1] = ColorSourceImage[tempAddress * 3 + 1] - BackgroundImage[cameraIndex][tempAddress * 3 + 1];
							colorDiff[2] = ColorSourceImage[tempAddress * 3 + 2] - BackgroundImage[cameraIndex][tempAddress * 3 + 2];

							if (colorDiff[0] < 4 && colorDiff[1] < 4 && colorDiff[2] < 4)
							{
								ShapeBinaryImage[tempAddress] = 0;
							}
						}
					}
				}
				else if (TempImage[tempAddress] == 2)
				{
					if ((maxRGBFactorSrcArry[tempAddress] & 0x0F) == (maxRGBFactorOstArry[tempAddress] & 0x0F))
					{
						colorDiff[0] = ColorSourceImage[tempAddress * 3 + 0] - BackgroundImage[cameraIndex][tempAddress * 3 + 0];
						colorDiff[1] = ColorSourceImage[tempAddress * 3 + 1] - BackgroundImage[cameraIndex][tempAddress * 3 + 1];
						colorDiff[2] = ColorSourceImage[tempAddress * 3 + 2] - BackgroundImage[cameraIndex][tempAddress * 3 + 2];

						if (colorDiff[0] < 4 && colorDiff[1] < 4 && colorDiff[2] < 4)
						{
							ShapeBinaryImage[tempAddress] = 0;
						}
					}
				}
			}
		}

		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (ShapeBinaryImage[tempAddress] == 1)
				{
					if ((maxRGBFactorSrcArry[tempAddress] & 0x0F) == (maxRGBFactorOstArry[tempAddress] & 0x0F))
					{
						colorDiff[0] = ColorSourceImage[tempAddress * 3 + 0] - BackgroundImage[cameraIndex][tempAddress * 3 + 0];
						colorDiff[1] = ColorSourceImage[tempAddress * 3 + 1] - BackgroundImage[cameraIndex][tempAddress * 3 + 1];
						colorDiff[2] = ColorSourceImage[tempAddress * 3 + 2] - BackgroundImage[cameraIndex][tempAddress * 3 + 2];

						if (!(abs(colorDiff[0]) > MAX_OBJECT_COLOR_DIFF || abs(colorDiff[1]) > MAX_OBJECT_COLOR_DIFF || abs(colorDiff[2]) > MAX_OBJECT_COLOR_DIFF))
						{
							ShapeBinaryImage[tempAddress] = 0;
						}
					}
				}
			}
		}

		/*
		memcpy(TempImage, ShapeBinaryImage, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;
				if (TempImage[tempAddress])
				{
					noiseCount = 0;

					for (r = 4; r <= 8; r += 4)
					{
						if (y - r > startY)
						{
							tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH;
							if (TempImage[tempAddress2] == 0)
							{
								noiseCount++;
								break;
							}
						}
					}

					for (r = 4; r <= 8; r += 4)
					{
						if (y + r < endY)
						{
							tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH;
							if (TempImage[tempAddress2] == 0)
							{
								noiseCount++;
								break;
							}
						}
					}

					if (noiseCount == 2)
					{
						for (r = 4; r <= 8; r += 4)
						{
							if (x - r > startX)
							{
								tempAddress2 = tempAddress - r;
								if (TempImage[tempAddress2] == 0)
								{
									noiseCount++;
									break;
								}
							}
						}

						for (r = 4; r <= 8; r += 4)
						{
							if (x + r < endX)
							{
								tempAddress2 = tempAddress + r;
								if (TempImage[tempAddress2] == 0)
								{
									noiseCount++;
									break;
								}
							}
						}
					}

					if (noiseCount >= 4)
					{
						ShapeBinaryImage[tempAddress] = 0;
					}
				}
			}
		}
		*/

		memset(maxRGBCount, 0, sizeof(int) * 3);
		for (y = startY; y < endY; y+=2)
		{
			for (x = startX; x < endX; x+=2)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (ShapeBinaryImage[tempAddress])
				{
					if ((maxRGBFactorSrcArry[tempAddress] & 0x0F))
					{
						mostRGB = (maxRGBFactorSrcArry[tempAddress] & 0x0F) - 1;
						if (ColorSourceImage[tempAddress * 3 + mostRGB] > BackgroundImage[cameraIndex][tempAddress * 3 + mostRGB])
						{
							maxRGBCount[mostRGB]++;
						}
					}
				}
			}
		}

		maxValue = 0;
		for (rgb = 0; rgb < 3; rgb++)
		{
			if (maxValue < maxRGBCount[rgb])
			{
				maxValue = maxRGBCount[rgb];
				maxRGBFactor = rgb;
			}
		}

		memset(maxRGBCount, 0, sizeof(int) * 3);
		for (y = startY; y < endY; y+=2)
		{
			for (x = startX; x < endX; x+=2)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (ShapeBinaryImage[tempAddress])
				{
					if ((maxRGBFactorSrcArry[tempAddress] & 0xF0))
					{
						mostRGB = ((maxRGBFactorSrcArry[tempAddress] & 0xF0) >> 4) - 1;
						maxRGBCount[mostRGB]++;
					}
				}
			}
		}

		maxValue = 0;
		for (rgb = 0; rgb < 3; rgb++)
		{
			if (maxValue < maxRGBCount[rgb])
			{
				maxValue = maxRGBCount[rgb];
				trdRGBFactor = rgb;
			}
		}

		memset(colorRate, 0, sizeof(int) * 3);
		tempCount = 0;
		for (y = startY; y < endY; y+=2)
		{
			for (x = startX; x < endX; x+=2)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (ShapeBinaryImage[tempAddress])
				{
					value = (maxRGBFactorSrcArry[tempAddress] & 0x0F);
					if (value)
					{
						value = value - 1;

						if (value == maxRGBFactor)
						{
							colorRate[0] += ColorRateImageSrcArr[tempAddress * 3 + 0];
							colorRate[1] += ColorRateImageSrcArr[tempAddress * 3 + 1];
							colorRate[2] += ColorRateImageSrcArr[tempAddress * 3 + 2];
							tempCount++;
						}
					}
				}
			}
		}

		if (tempCount)
		{
			colorRate[0] /= tempCount;
			colorRate[1] /= tempCount;
			colorRate[2] /= tempCount;

			colorSum = colorRate[0] + colorRate[1] + colorRate[2];
			if (colorSum)
			{
				avgTabletColorRate = colorRate[maxRGBFactor] * 100 / colorSum;

				if (avgTabletColorRate >= CHROMATIC_TABLET_VALUE)
				{
					chromaticThreshold = avgTabletColorRate * 0.9;
					for (y = startY; y < endY; y++)
					{
						for (x = startX; x < endX; x++)
						{
							tempAddress = MAX_IMAGE_WIDTH * y + x;

							if ((maxRGBFactorSrcArry[tempAddress] & 0x0F) && ShapeBinaryImage[tempAddress])
							{
								mostRGB = (maxRGBFactorSrcArry[tempAddress] & 0x0F) - 1;

								colorRate[0] = ColorRateImageSrcArr[tempAddress * 3 + 0];
								colorRate[1] = ColorRateImageSrcArr[tempAddress * 3 + 1];
								colorRate[2] = ColorRateImageSrcArr[tempAddress * 3 + 2];

								colorSum = colorRate[0] + colorRate[1] + colorRate[2];

								if (colorSum)
								{
									srcColorRate = colorRate[maxRGBFactor] * 100 / colorSum;

									if (srcColorRate < chromaticThreshold)
									{
										ShapeBinaryImage[tempAddress] = 0;
									}
								}
								else
								{
									ShapeBinaryImage[tempAddress] = 0;
								}
							}
						}
					}
				}
				else if (avgTabletColorRate >= CHROMATIC_TABLET_VALUE2)
				{
					for (y = startY; y < endY; y++)
					{
						for (x = startX; x < endX; x++)
						{
							tempAddress = MAX_IMAGE_WIDTH * y + x;

							if ((maxRGBFactorSrcArry[tempAddress] & 0x0F) && ShapeBinaryImage[tempAddress])
							{
								mostRGB = (maxRGBFactorSrcArry[tempAddress] & 0x0F) - 1;

								if (mostRGB != maxRGBFactor)
								{
									ShapeBinaryImage[tempAddress] = 0;
								}
							}

							if ((maxRGBFactorSrcArry[tempAddress] & 0xF0) && ShapeBinaryImage[tempAddress])
							{
								mostRGB = ((maxRGBFactorSrcArry[tempAddress] & 0xF0) >> 4) - 1;

								if (mostRGB != trdRGBFactor)
								{
									ShapeBinaryImage[tempAddress] = 0;
								}
							}
						}
					}
				}
        else
        {
          // 무채색 -> 벨트보다 어두운 무채색이있다...  검사못하는거지뭐
          for (y = startY; y < endY; y++)
					{
						for (x = startX; x < endX; x++)
						{
							tempAddress = MAX_IMAGE_WIDTH * y + x;

							if (ShapeBinaryImage[tempAddress])
							{
								colorDiff[0] = ColorSourceImage[tempAddress * 3 + 0] - BackgroundImage[cameraIndex][tempAddress * 3 + 0];
                colorDiff[1] = ColorSourceImage[tempAddress * 3 + 1] - BackgroundImage[cameraIndex][tempAddress * 3 + 1];
                colorDiff[2] = ColorSourceImage[tempAddress * 3 + 2] - BackgroundImage[cameraIndex][tempAddress * 3 + 2];

                if ((colorDiff[0] < MIN_OBJECT_COLOR_DIFF && colorDiff[1] < MIN_OBJECT_COLOR_DIFF) ||
                    (colorDiff[1] < MIN_OBJECT_COLOR_DIFF && colorDiff[2] < MIN_OBJECT_COLOR_DIFF) ||
                    (colorDiff[0] < MIN_OBJECT_COLOR_DIFF && colorDiff[2] < MIN_OBJECT_COLOR_DIFF))
                {
                  ShapeBinaryImage[tempAddress] = 0;
                }
							}
						}
					}
        }
			}
		}

		memcpy(TempImage, ShapeBinaryImage, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;
				if (TempImage[tempAddress] == 0)
				{
					leftSW = rightSW = bottomSW = topSW = 0;

					for (r = 12; r >= 4; r -= 4)
					{
						if (x - r > startX)
						{
							tempAddress2 = tempAddress - r;
							if (TempImage[tempAddress2])
							{
								leftSW = 1;
								break;
							}
						}
					}
					if (!leftSW) continue;

					for (r = 12; r >= 4; r -= 4)
					{
						if (x + r < endX)
						{
							tempAddress2 = tempAddress + r;
							if (TempImage[tempAddress2])
							{
								rightSW = 1;
								break;
							}
						}
					}
					if (!rightSW) continue;

					for (r = 12; r >= 4; r -= 4)
					{
						if (y - r > startY)
						{
							tempAddress2 = tempAddress - r * MAX_IMAGE_WIDTH;
							if (TempImage[tempAddress2])
							{
								topSW = 1;
								break;
							}
						}
					}
					if (!topSW) continue;

					for (r = 12; r >= 4; r -= 4)
					{
						if (y + r < endY)
						{
							tempAddress2 = tempAddress + r * MAX_IMAGE_WIDTH;
							if (TempImage[tempAddress2])
							{
								bottomSW = 1;
								break;
							}
						}
					}
					if (!bottomSW) continue;

					ShapeBinaryImage[tempAddress] = 1;
				}
			}
		}

		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;
				tempAddress2 = (MAX_IMAGE_WIDTH / 2) * (y / 2) + (x / 2);

				if (ShapeBinaryImage[tempAddress])
				{
					smallBinaryImage[tempAddress2] = 1;
				}
			}
		}

		maxLabelN = LabellingForTabletImage(halfLabelImage, smallBinaryImage, startX / 2, endX / 2, startY / 2, endY / 2, MAX_IMAGE_WIDTH / 2, MAX_IMAGE_HEIGHT / 2);

		if (maxLabelN)
		{
			for (y = startY; y < endY; y++)
			{
				for (x = startX; x < endX; x++)
				{
					tempAddress = MAX_IMAGE_WIDTH * y + x;
					tempAddress2 = (MAX_IMAGE_WIDTH / 2) * (y / 2) + (x / 2);

					if (ShapeBinaryImage[tempAddress])
					{
						if (halfLabelImage[tempAddress2] != maxLabelN)
						{
							ShapeBinaryImage[tempAddress] = 0;
						}
					}
				}
			}
		}

		// 채우기 -> 인쇄, 이물 등으로 인해 정제의 내부가 binary로 포함되지 않을 수 있음
		for (y = startY; y < endY; y++)
		{
			minX = MAX_IMAGE_WIDTH;
			maxX = 0;

			for (x = startX; x < endX; x+=2)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (ShapeBinaryImage[tempAddress])
				{
					if (minX > x) minX = x;
					if (maxX < x) maxX = x;
				}
			}

			for (x = minX; x <= maxX; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				mostRGB = (maxRGBFactorSrcArry[tempAddress] & 0x0F) - 1;
				if (mostRGB == maxRGBFactor)
				{
					ShapeBinaryImage[tempAddress] = 1;
				}
			}
		}

		beltShiftSize = 32;
		memset(TempImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (ShapeBinaryImage[tempAddress])
				{
					topEndSW = bottomEndSW = 0;
					for (r = 4; r <= beltShiftSize; r += 4)
					{
						if (y - r > startY)
						{
							if (!ShapeBinaryImage[tempAddress - r * MAX_IMAGE_WIDTH])
							{
								topEndSW = 1;
								break;
							}
						}
					}

					if (!topEndSW) continue;

					for (r = 4; r <= beltShiftSize; r += 4)
					{
						if (y + r < endY)
						{
							if (!ShapeBinaryImage[tempAddress + r * MAX_IMAGE_WIDTH])
							{
								bottomEndSW = 1;
								break;
							}
						}
					}

					if (topEndSW && bottomEndSW)
					{
						TempImage[tempAddress] = 1;
					}
				}
			}
		}
		// end

		// 벨트예상군 제거
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (TempImage[tempAddress])
				{
					ShapeBinaryImage[tempAddress] = 0;
				}
			}
		}

		// 제거된 영역 중 정제로 예상되는 부분 복원
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (TempImage[tempAddress])
				{
					topEndSW = bottomEndSW = 0;

					for (r = 4; r <= beltShiftSize; r += 4)
					{
						if (y - r > startY)
						{
							if (ShapeBinaryImage[tempAddress - r * MAX_IMAGE_WIDTH])
							{
								TempImage[tempAddress] = 2;
								topEndSW = 1;
								break;
							}
						}
					}

					if (!topEndSW)
					{
						for (r = 4; r <= beltShiftSize; r += 4)
						{
							if (y + r < endY)
							{
								if (ShapeBinaryImage[tempAddress + r * MAX_IMAGE_WIDTH])
								{
									TempImage[tempAddress] = 2;
									break;
								}
							}
						}
					}
				}
			}
		}

		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = y * MAX_IMAGE_WIDTH + x;

				if (TempImage[tempAddress] == 2)
				{
					ShapeBinaryImage[tempAddress] = 1;
				}
			}
		}

		ProtoTabletCenterX = ProtoTabletCenterY = tempCount = 0;
		avgColorValue = 0;
		for (y = startY; y < endY; y += 2)
		{
			for (x = startX; x < endX; x += 2)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;
				if (ShapeBinaryImage[tempAddress])
				{
					ProtoTabletCenterX += x;
					ProtoTabletCenterY += y;
					avgColorValue += ColorSourceImage[tempAddress * 3 + maxRGBFactor];
					tempCount++;
				}
			}
		}

		if (tempCount)
		{
			ProtoTabletCenterX /= tempCount;
			ProtoTabletCenterY /= tempCount;
			avgColorValue /= tempCount;
		}
		else
		{
			memset(ShapeBinaryImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

			ProtoTabletCenterX = MAX_IMAGE_WIDTH / 2;
			ProtoTabletCenterY = MAX_IMAGE_HEIGHT / 2;
			avgColorValue = threshold;
		}

		bottomCenterY = tempCount = 0;
		for (y = ProtoTabletCenterY; y < endY; y += 2)
		{
			for (x = startX; x < endX; x += 2)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (ShapeBinaryImage[tempAddress])
				{
          colorDiff[maxRGBFactor] = ColorSourceImage[tempAddress * 3 + maxRGBFactor] - BackgroundImage[cameraIndex][tempAddress * 3 + maxRGBFactor];

          if(colorDiff[maxRGBFactor] > 4)
          {
					  bottomCenterY += y;
					  tempCount++;
          }
				}
			}
		}

		if (tempCount)
		{
			bottomCenterY /= tempCount;
			centerPassCount = 0;

			for (x = startX; x < endX; x += 2)
			{
				for (y = ProtoTabletCenterY; y < endY; y+=2)
				{
					tempAddress = MAX_IMAGE_WIDTH * y + x;

					if (ShapeBinaryImage[tempAddress])
					{
						if (y >= bottomCenterY)
						{
							centerPassCount++;
							break;
						}
					}
				}
			}

			realTabletThreshold = threshold;
			for (shift = avgColorValue; shift >= threshold; shift -= 4)
			{
				tempCenterPassCount = 0;
				for (x = startX; x < endX; x += 2)
				{
					for (y = ProtoTabletCenterY; y < endY; y+=2)
					{
						tempAddress = MAX_IMAGE_WIDTH * y + x;

						if (ShapeBinaryImage[tempAddress])
						{
							if (ColorSourceImage[tempAddress * 3 + maxRGBFactor] >= shift)
							{
								if (y >= bottomCenterY)
								{
									tempCenterPassCount++;
									break;
								}
							}
						}
					}
				}

				if (tempCenterPassCount >= centerPassCount * 0.9)
				{
					realTabletThreshold = max(threshold, shift * 0.7);
					break;
				}
			}

      for (y = startY; y < endY; y++)
      {
        for (x = startX; x < endX; x++)
        {
          tempAddress = MAX_IMAGE_WIDTH * y + x;

          if (ShapeBinaryImage[tempAddress])
          {
            if (ColorSourceImage[tempAddress * 3 + maxRGBFactor] < realTabletThreshold)
            {
              ShapeBinaryImage[tempAddress] = 0;            
            }
          }
        }
      }

      // 채우기 -> 인쇄, 이물 등으로 인해 정제의 내부가 binary로 포함되지 않을 수 있음
      for (y = startY; y < endY; y++)
      {
        minX = MAX_IMAGE_WIDTH;
        maxX = 0;

        for (x = startX; x < endX; x++)
        {
          tempAddress = y * MAX_IMAGE_WIDTH + x;

          if (ShapeBinaryImage[tempAddress])
          {
            if (minX > x) minX = x;
            if (maxX < x) maxX = x;
          }
        }

        for (x = minX; x <= maxX; x++)
        {
          tempAddress = y * MAX_IMAGE_WIDTH + x;

          mostRGB = (maxRGBFactorSrcArry[tempAddress] & 0x0F) - 1;
          if (mostRGB == maxRGBFactor)
          {
            ShapeBinaryImage[tempAddress] = 1;
          }
        }
      }
		}

		memcpy(TempImage, ShapeBinaryImage, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		Erode(TempImage, ShapeBinaryImage, startX, endX, startY, endY, 2);

		memcpy(TempImage, ShapeBinaryImage, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		Dilate(TempImage, ShapeBinaryImage, startX, endX, startY, endY, 2);

		memcpy(ObjectAreaImage[cameraIndex], ShapeBinaryImage, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

		short binaryBottomEndPosition[MAX_IMAGE_WIDTH];

		for (int m = 0; m < MAX_IMAGE_WIDTH; m++)
		{
			binaryBottomEndPosition[m] = 0;
		}

		int startBinX, endBinX;
		startBinX = MAX_IMAGE_WIDTH;
		endBinX = 0;

		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (ObjectAreaImage[cameraIndex][tempAddress])
				{
					if (binaryBottomEndPosition[x] <= y)
					{
						binaryBottomEndPosition[x] = y;
					}

					if (startBinX >= x)
					{
						startBinX = x;
					}

					if (endBinX <= x)
					{
						endBinX = x;
					}
				}
			}
		}

		float ppmm = MAX_IMAGE_WIDTH / 30; // fov 30mm

		int tabletConvHeight = ppmm * ProductData.TabletSideThick * 3 / 7;

		int tempX1, tempX2;
		switch (cameraIndex + 1)
		{
		case SD1_2D_SIDE_FACE_M45_CAMERA_INDEX:
		case SD2_2D_SIDE_FACE_M45_CAMERA_INDEX:
		case SD1_2D_OTHER_SIDE_FACE_M45_CAMERA_INDEX:
		case SD2_2D_OTHER_SIDE_FACE_M45_CAMERA_INDEX:

			tempX1 = startBinX + 20;
			tempX2 = (startBinX + endBinX) / 2;
			break;

		case SD1_2D_SIDE_FACE_00_CAMERA_INDEX:
		case SD2_2D_SIDE_FACE_00_CAMERA_INDEX:
		case SD1_2D_OTHER_SIDE_FACE_00_CAMERA_INDEX:
		case SD2_2D_OTHER_SIDE_FACE_00_CAMERA_INDEX:

			tempX1 = startBinX + 40;
			tempX2 = endBinX - 40;
			break;

		case SD1_2D_SIDE_FACE_P45_CAMERA_INDEX:
		case SD2_2D_SIDE_FACE_P45_CAMERA_INDEX:
		case SD1_2D_OTHER_SIDE_FACE_P45_CAMERA_INDEX:
		case SD2_2D_OTHER_SIDE_FACE_P45_CAMERA_INDEX:

			tempX1 = (startBinX + endBinX) / 2;
			tempX2 = endBinX - 20;
			break;
		}

		for (x = tempX1; x <= tempX2; x++)
		{
			if (binaryBottomEndPosition[x])
			{
				sideCenterPosData[cameraIndex][sideCenterPosDataCount[cameraIndex] * 2 + 0] = x;
				sideCenterPosData[cameraIndex][sideCenterPosDataCount[cameraIndex] * 2 + 1] = binaryBottomEndPosition[x] - tabletConvHeight;
				sideCenterPosDataCount[cameraIndex]++;
			}
		}

		for (y = startY; y < endY; y++)
		{
			ptr = (Byte*)srcImage->Picture->Bitmap->ScanLine[y];
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (ObjectAreaImage[cameraIndex][tempAddress])
				{
					if (ViewOptionCheckBox->Checked == 0)
					{
						if (ObjectAreaImage[cameraIndex][tempAddress - 4] == 0 ||
							ObjectAreaImage[cameraIndex][tempAddress + 4] == 0 ||
							ObjectAreaImage[cameraIndex][tempAddress - 4 * MAX_IMAGE_WIDTH] == 0 ||
							ObjectAreaImage[cameraIndex][tempAddress + 4 * MAX_IMAGE_WIDTH] == 0)
						{
							ptr[3 * x + 0] = 0;
							ptr[3 * x + 1] = 0;
							ptr[3 * x + 2] = 255;
						}
					}
					else
					{
						ptr[3 * x + 0] = ColorSourceImage[tempAddress * 3 + 2];
						ptr[3 * x + 1] = ColorSourceImage[tempAddress * 3 + 1] / 2;
						ptr[3 * x + 2] = ColorSourceImage[tempAddress * 3 + 0];
					}
				}
			}
		}

		if (sideCenterPosDataCount[cameraIndex])
		{
			for (int m = 0; m < sideCenterPosDataCount[cameraIndex]; m++)
			{
				x = sideCenterPosData[cameraIndex][m * 2 + 0];
				y = sideCenterPosData[cameraIndex][m * 2 + 1];

				if (x > startX && x < endX && y > startY && y < endY)
				{
					for (int j = y - 2; j <= y + 2; j++)
					{
						ptr = (Byte*)srcImage->Picture->Bitmap->ScanLine[j];
						for (int i = x - 2; i <= x + 2; i++)
						{
							if (ViewOptionCheckBox->Checked == 0)
							{
								tempAddress = MAX_IMAGE_WIDTH * j + i;

								ptr[3 * i + 0] = 255 - ColorSourceImage[tempAddress * 3 + 0];
								ptr[3 * i + 1] = 255 - ColorSourceImage[tempAddress * 3 + 1];
								ptr[3 * i + 2] = 255 - ColorSourceImage[tempAddress * 3 + 2];
							}
							else
							{
								ptr[3 * i + 0] = 255;
								ptr[3 * i + 1] = 255;
								ptr[3 * i + 2] = 255;

								ptr[3 * i + maxRGBFactor] = 0;
							}
						}
					}
				}
			}
		}
	}
	else
	{
		// simluation test
		for (y = startY; y < endY; y++)
		{
			ptr = (Byte*)srcImage->Picture->Bitmap->ScanLine[y];
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (x > 320 - 100 && x < 320 + 100 && y > 240 - 50 && y < 240 + 50)
				{
					ObjectAreaImage[cameraIndex][tempAddress] = 1;
				}
			}
		}

		memset(HalfLabelImage, 0, (MAX_IMAGE_WIDTH / 2) * (MAX_IMAGE_HEIGHT / 2) * sizeof(short));
		memset(smallBinaryImage, 0, (MAX_IMAGE_WIDTH / 2) * (MAX_IMAGE_HEIGHT / 2));

		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;
				tempAddress2 = (MAX_IMAGE_WIDTH / 2) * (y / 2) + (x / 2);

				if (ObjectAreaImage[cameraIndex][tempAddress])
				{
					smallBinaryImage[tempAddress2] = 1;
				}
			}
		}

		memset(ObjectAreaImage[cameraIndex], 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
		int maxLabelN = LabellingForTabletImage(HalfLabelImage, smallBinaryImage, startX / 2, endX / 2, startY / 2, endY / 2, MAX_IMAGE_WIDTH / 2, MAX_IMAGE_HEIGHT / 2);

		if (maxLabelN)
		{
			for (y = startY; y < endY; y++)
			{
				for (x = startX; x < endX; x++)
				{
					tempAddress = MAX_IMAGE_WIDTH * y + x;
					tempAddress2 = (MAX_IMAGE_WIDTH / 2) * (y / 2) + (x / 2);

					if (HalfLabelImage[tempAddress2] == maxLabelN)
					{
						ObjectAreaImage[cameraIndex][tempAddress] = 1;
					}
				}
			}

			int minX, maxX;
			for (y = startY; y < endY; y++)
			{
				minX = SYSTEM_CAMERA_WIDTH;
				maxX = 0;

				for (x = startX; x < endX; x++)
				{
					tempAddress = y * SYSTEM_CAMERA_WIDTH + x;

					if (ObjectAreaImage[cameraIndex][tempAddress])
					{
						if (minX > x) minX = x;
						if (maxX < x) maxX = x;
					}
				}

				for (x = minX; x <= maxX; x++)
				{
					tempAddress = y * SYSTEM_CAMERA_WIDTH + x;
					ObjectAreaImage[cameraIndex][tempAddress] = 1;
				}
			}
		}

		for (y = startY; y < endY; y++)
		{
			ptr = (Byte*)srcImage->Picture->Bitmap->ScanLine[y];
			for (x = startX; x < endX; x++)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (ObjectAreaImage[cameraIndex][tempAddress])
				{
					if (ViewOptionCheckBox->Checked == 0)
					{
						if (ObjectAreaImage[cameraIndex][tempAddress - 4] == 0 ||
							ObjectAreaImage[cameraIndex][tempAddress + 4] == 0 ||
							ObjectAreaImage[cameraIndex][tempAddress - 4 * MAX_IMAGE_WIDTH] == 0 ||
							ObjectAreaImage[cameraIndex][tempAddress + 4 * MAX_IMAGE_WIDTH] == 0)
						{
							ptr[3 * x + 0] = 0;
							ptr[3 * x + 1] = 0;
							ptr[3 * x + 2] = 255;
						}
					}
					else
					{
						ptr[3 * x + 0] = ColorSourceImage[tempAddress * 3 + 2];
						ptr[3 * x + 1] = ColorSourceImage[tempAddress * 3 + 1] / 2;
						ptr[3 * x + 2] = ColorSourceImage[tempAddress * 3 + 0];
					}
				}
			}
		}
	}

	srcImage->Refresh();


	/*
	2020-04-17
	1) 분진이 잔뜩쌓인 상태로 벨트학습을 진행한 후 검사를 시작 -> 기계에서 정제 안착과정에서 분진이 떨어져버림 -> 해당 부분이 레퍼런스보다 어두워지게 될것 -> 정제로 인식하게 될텐데 어떻게 할것인가
	1-1) 우선 검사에 필요한 최저 밝기로 세팅하므로 분진이 지워진다고하더라도 검사에 영향이 있을것 같진 않음
	1-2) 정면은 40기준 밝기면 충분할것 같고, 측면은 사용자가 세팅하니까 괜찮지않겠냐..
	1-3) 정제 안착과정에서 분진이 안떨어져나갈수도있지않냐
	1-4) 일단 이경우에는 벨트를 청소하면 괜찮아지긴하던데..
	*/
}

void __fastcall TAutoBrightnessSettingForm::Erode(unsigned char *srcImage, unsigned char *dstImage, int startX, int endX, int startY, int endY, int maskSize)
{
	int x, y;
	int tempAddress, tempAddress2;
	int wm, hm;
	int tempX, tempY;
	int ErodeSW;

	wm = maskSize / 2;
	hm = maskSize / 2;

	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;

			if (srcImage[tempAddress])
			{
				ErodeSW = 0;

				if (srcImage[tempAddress - hm] == 0 ||
					srcImage[tempAddress + hm] == 0 ||
					srcImage[tempAddress - wm * MAX_IMAGE_WIDTH] == 0 ||
					srcImage[tempAddress + wm * MAX_IMAGE_WIDTH] == 0)
				{
					ErodeSW = 1;
				}

				if (ErodeSW)
				{
					for (tempY = y - hm; tempY <= y + hm; tempY++)
					{
						for (tempX = x - wm; tempX <= x + wm; tempX++)
						{
							tempAddress2 = MAX_IMAGE_WIDTH * tempY + tempX;

							dstImage[tempAddress2] = 0;
						}
					}
				}
			}
		}
	}
}

void __fastcall TAutoBrightnessSettingForm::Dilate(unsigned char *srcImage, unsigned char *dstImage, int startX, int endX, int startY, int endY, int maskSize)
{
	int x, y;
	int tempAddress, tempAddress2;
	int wm, hm;
	int tempX, tempY;
	int DilateSW;

	wm = maskSize / 2;
	hm = maskSize / 2;

	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = MAX_IMAGE_WIDTH * y + x;

			if (srcImage[tempAddress] == 0)
			{
				DilateSW = 0;

				if (srcImage[tempAddress - hm] ||
					srcImage[tempAddress + hm] ||
					srcImage[tempAddress - wm * MAX_IMAGE_WIDTH] ||
					srcImage[tempAddress + wm * MAX_IMAGE_WIDTH])
				{
					DilateSW = 1;
				}

				if (DilateSW)
				{
					for (tempY = y - hm; tempY <= y + hm; tempY++)
					{
						for (tempX = x - wm; tempX <= x + wm; tempX++)
						{
							if (tempX > startX && tempX < endX && tempY > startY && tempY < endY)
							{
								tempAddress2 = MAX_IMAGE_WIDTH * tempY + tempX;

								dstImage[tempAddress2] = 1;
							}
						}
					}
				}
			}
		}
	}
}
