#pragma once

#include "stdafx.h"
#include "CPU_Func_Library.h"
#include "CUDA_Func_Library.cuh"
#include "Webcam_Func_Library.h"
#include <opencv2/opencv.hpp>
#include "MyFormHistogram.h"

struct UIValues
{
	int CPUthreads;
	int selectedGPU;
	int GPUthreads;
	int method;
	int type;
	bool negative;
	bool threshold;
	bool CPU;
	bool GPU;
	double threshold1;
	double threshold2;
	double thresholdEdge;
	int k;
	int maxIterations;
	double webcamDelay;
};

UIValues values;

namespace Image_Segmentation_on_GPU {

	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Diagnostics;
	using namespace System::Drawing;
	using namespace System::Management;
	using namespace cv;

	/// <summary>
	/// Summary for MyForm
	/// </summary>
	public ref class MyForm : public System::Windows::Forms::Form
	{
	public:
		// Input, Output and webcam bitmaps
		Bitmap^ bmpIn;
		Bitmap^ bmpOut;
		Bitmap^ bmpWebIn;
		Bitmap^ bmpWebOut;
		// creating stopWatch object;
		Stopwatch^ sWatch;
		int miliseconds = 0;
		char seconds = 0;
		char minutes = 0;
		Int16 iterations;
		CamCapture^ camera;



	public:
		MyFormHistogram^ Histogram;

	public:
		void ClearPictureBoxes()
		{
			// clear all image data from bitmaps and pictureBoxes
			if (bmpIn != nullptr)
			{
				delete bmpIn;
				pictureBox_Input->Image = nullptr;
			}
			if (bmpOut != nullptr)
			{
				delete bmpOut;
				pictureBox_Output->Image = nullptr;
			}
			// run garbage collector
			System::GC::Collect();
		}

		MyForm(void)
		{
			InitializeComponent();

			//
			//TODO: Add the constructor code here
			//
		}

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~MyForm()
		{
			if (components)
			{
				delete components;
				//ClearPictureBoxes();
			}
		}

	private: System::Windows::Forms::NumericUpDown^  numericUpDown_threshold_2;
	private: System::Windows::Forms::GroupBox^  groupBox_ImageAdjust;
	private: System::Windows::Forms::CheckBox^  checkBox_Negative;
	private: System::Windows::Forms::NumericUpDown^  numericUpDown_adjustTreshold;
	private: System::Windows::Forms::ToolStripStatusLabel^  label_CaptureDevices;
	private: System::Windows::Forms::ToolStripStatusLabel^  label_CaptureDevices_Num;
	private: System::Windows::Forms::ToolStripMenuItem^  imageToolStripMenuItem;
	private: System::Windows::Forms::ToolStripMenuItem^  histogramToolStripMenuItem;
	private: System::Windows::Forms::ToolStripMenuItem^  informationToolStripMenuItem;
	private: System::Windows::Forms::ToolStripStatusLabel^  toolStripStatusLabel_spring;
	private: System::Windows::Forms::ToolStripStatusLabel^  toolStripStatusLabel_Time;
	private: System::Windows::Forms::ToolStripMenuItem^  useOutputImageToolStripMenuItem;
	private: System::Windows::Forms::Label^  label_Max_Iterations;
	private: System::Windows::Forms::Label^  label_Clusters;
	private: System::Windows::Forms::NumericUpDown^  numericUpDown_Clusters;
	private: System::Windows::Forms::NumericUpDown^  numericUpDown_Iterations;
	private: System::Windows::Forms::ToolStripStatusLabel^  toolStripStatusLabel_Iterations;
	private: System::ComponentModel::BackgroundWorker^  backgroundWorker_Webcam;
	private: System::ComponentModel::BackgroundWorker^  backgroundWorker;
	private: System::Windows::Forms::NumericUpDown^  numericUpDown_threshold_1;
	private: System::Windows::Forms::CheckBox^  checkBox_Treshold;
	private: System::Windows::Forms::GroupBox^  groupBox_Webcam;
	private: System::Windows::Forms::ToolStripMenuItem^  inputToolStripMenuItem;
	private: System::Windows::Forms::ToolStripMenuItem^  WebcamFileToolStripMenuItem;
	private: System::Windows::Forms::ComboBox^  comboBox_Webcam_device;
	private: System::Windows::Forms::Button^  button_Webcam_Single;
	private: System::Windows::Forms::Button^  button_Webcam_StartStop;
	private: System::Windows::Forms::Label^  label_Webcam_interval;
	private: System::Windows::Forms::NumericUpDown^  numericUpDown_WebcamInterval;
	private: System::Windows::Forms::Button^  button_WebcamIntervalMinus;
	private: System::Windows::Forms::Button^  button_WebcamIntervalPlus;
	private: System::Windows::Forms::Timer^  timer_Time;
	private: System::Windows::Forms::Label^  label_CPU_Core_Count;
	private: System::Windows::Forms::GroupBox^  groupBox_Methods;
	private: System::Windows::Forms::ComboBox^  comboBox_Methods;
	private: System::Windows::Forms::ToolStripStatusLabel^  label_CPU_Time;
	private: System::Windows::Forms::ComboBox^  comboBox_Method_Type;
	private: System::Windows::Forms::NumericUpDown^  numericUpDown_CUDA_threads;
	private: System::Windows::Forms::Label^  label_CUDA_threads;
	private: System::Windows::Forms::ToolStripStatusLabel^  label_CUDA_Time;
	private: System::Windows::Forms::ToolStripStatusLabel^  label_OpenCL_Time;
	private: System::Windows::Forms::NumericUpDown^  numericUpDown_CPU_Thrads;
	private: System::Windows::Forms::Label^  label_CPU_Use_Threads;
	private: System::Windows::Forms::Label^  label_Methods_Type;
	private: System::Windows::Forms::Label^  label_CPU_Vendor;
	private: System::Windows::Forms::TextBox^  label_CPU_Vendor_text;
	private: System::Windows::Forms::TableLayoutPanel^  tableLayoutPanel;
	private: System::Windows::Forms::ToolTip^  toolTip;
	private: System::Windows::Forms::MenuStrip^  menuStrip;
	private: System::Windows::Forms::ToolStripMenuItem^  fileToolStripMenuItem;
	private: System::Windows::Forms::ToolStripMenuItem^  openToolStripMenuItem;
	private: System::Windows::Forms::ToolStripMenuItem^  saveToolStripMenuItem;
	private: System::Windows::Forms::ToolStripSeparator^  toolStripSeparator1;
	private: System::Windows::Forms::ToolStripMenuItem^  exitToolStripMenuItem;
	private: System::Windows::Forms::ToolStripMenuItem^  helpToolStripMenuItem;
	private: System::Windows::Forms::ToolStripMenuItem^  aboutToolStripMenuItem;
	private: System::Windows::Forms::SaveFileDialog^  saveFileDialog;
	private: System::Windows::Forms::ToolStripSeparator^  toolStripSeparator2;
	private: System::Windows::Forms::ToolStripMenuItem^  closeToolStripMenuItem;
	private: System::Windows::Forms::ToolStripMenuItem^  segmentationToolStripMenuItem;
	private: System::Windows::Forms::ToolStripMenuItem^  startToolStripMenuItem;
	private: System::Windows::Forms::ToolStripMenuItem^  stopToolStripMenuItem;
	private: System::Windows::Forms::PictureBox^  pictureBox_Input;
	private: System::Windows::Forms::PictureBox^  pictureBox_Output;
	private: System::Windows::Forms::GroupBox^  groupBox_CPU_CUDA_Processor;

	private: System::Windows::Forms::RadioButton^  radioButton_CUDA;
	private: System::Windows::Forms::RadioButton^  radioButton_CPU;
	private: System::Windows::Forms::OpenFileDialog^  openFileDialog;
	private: System::Windows::Forms::Label^  label_InputImage;
	private: System::Windows::Forms::Label^  label_OutputImage;
	private: System::Windows::Forms::ComboBox^  comboBoxCUDASelect;
	private: System::Windows::Forms::GroupBox^  groupBox_GPU_select;
	private: System::Windows::Forms::Button^  button_GPU_info;
	private: System::Windows::Forms::StatusStrip^  statusStrip;
	private: System::Windows::Forms::ToolStripStatusLabel^  label_CUDAdevices;
	private: System::Windows::Forms::ToolStripStatusLabel^  label_CUDAdevices_Num;


	private: System::Windows::Forms::GroupBox^  groupBox_CPU_Info;
	private: System::Windows::Forms::Label^  label_CPU_Model;
	private: System::Windows::Forms::Label^  label_CPU_Clock;
	private: System::Windows::Forms::Label^  label_CPU_Threads_Count;
	private: System::Windows::Forms::TextBox^  label_CPU_Model_text;


	private: System::ComponentModel::IContainer^  components;

	private:
		/// <summary>
		/// Required designer variable.
		/// </summary>


#pragma region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		void InitializeComponent(void)
		{
			this->components = (gcnew System::ComponentModel::Container());
			System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager(MyForm::typeid));
			this->pictureBox_Input = (gcnew System::Windows::Forms::PictureBox());
			this->pictureBox_Output = (gcnew System::Windows::Forms::PictureBox());
			this->groupBox_CPU_CUDA_Processor = (gcnew System::Windows::Forms::GroupBox());
			this->radioButton_CUDA = (gcnew System::Windows::Forms::RadioButton());
			this->radioButton_CPU = (gcnew System::Windows::Forms::RadioButton());
			this->openFileDialog = (gcnew System::Windows::Forms::OpenFileDialog());
			this->label_InputImage = (gcnew System::Windows::Forms::Label());
			this->label_OutputImage = (gcnew System::Windows::Forms::Label());
			this->comboBoxCUDASelect = (gcnew System::Windows::Forms::ComboBox());
			this->groupBox_GPU_select = (gcnew System::Windows::Forms::GroupBox());
			this->label_CUDA_threads = (gcnew System::Windows::Forms::Label());
			this->numericUpDown_CUDA_threads = (gcnew System::Windows::Forms::NumericUpDown());
			this->button_GPU_info = (gcnew System::Windows::Forms::Button());
			this->statusStrip = (gcnew System::Windows::Forms::StatusStrip());
			this->label_CUDAdevices = (gcnew System::Windows::Forms::ToolStripStatusLabel());
			this->label_CUDAdevices_Num = (gcnew System::Windows::Forms::ToolStripStatusLabel());
			this->label_CaptureDevices = (gcnew System::Windows::Forms::ToolStripStatusLabel());
			this->label_CaptureDevices_Num = (gcnew System::Windows::Forms::ToolStripStatusLabel());
			this->label_CPU_Time = (gcnew System::Windows::Forms::ToolStripStatusLabel());
			this->label_CUDA_Time = (gcnew System::Windows::Forms::ToolStripStatusLabel());
			this->label_OpenCL_Time = (gcnew System::Windows::Forms::ToolStripStatusLabel());
			this->toolStripStatusLabel_Iterations = (gcnew System::Windows::Forms::ToolStripStatusLabel());
			this->toolStripStatusLabel_spring = (gcnew System::Windows::Forms::ToolStripStatusLabel());
			this->toolStripStatusLabel_Time = (gcnew System::Windows::Forms::ToolStripStatusLabel());
			this->groupBox_CPU_Info = (gcnew System::Windows::Forms::GroupBox());
			this->label_CPU_Use_Threads = (gcnew System::Windows::Forms::Label());
			this->numericUpDown_CPU_Thrads = (gcnew System::Windows::Forms::NumericUpDown());
			this->label_CPU_Vendor = (gcnew System::Windows::Forms::Label());
			this->label_CPU_Vendor_text = (gcnew System::Windows::Forms::TextBox());
			this->label_CPU_Core_Count = (gcnew System::Windows::Forms::Label());
			this->label_CPU_Model_text = (gcnew System::Windows::Forms::TextBox());
			this->label_CPU_Threads_Count = (gcnew System::Windows::Forms::Label());
			this->label_CPU_Clock = (gcnew System::Windows::Forms::Label());
			this->label_CPU_Model = (gcnew System::Windows::Forms::Label());
			this->tableLayoutPanel = (gcnew System::Windows::Forms::TableLayoutPanel());
			this->toolTip = (gcnew System::Windows::Forms::ToolTip(this->components));
			this->button_Webcam_StartStop = (gcnew System::Windows::Forms::Button());
			this->numericUpDown_WebcamInterval = (gcnew System::Windows::Forms::NumericUpDown());
			this->numericUpDown_Iterations = (gcnew System::Windows::Forms::NumericUpDown());
			this->backgroundWorker = (gcnew System::ComponentModel::BackgroundWorker());
			this->menuStrip = (gcnew System::Windows::Forms::MenuStrip());
			this->fileToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
			this->openToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
			this->saveToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
			this->toolStripSeparator2 = (gcnew System::Windows::Forms::ToolStripSeparator());
			this->closeToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
			this->toolStripSeparator1 = (gcnew System::Windows::Forms::ToolStripSeparator());
			this->exitToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
			this->imageToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
			this->histogramToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
			this->informationToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
			this->inputToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
			this->WebcamFileToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
			this->useOutputImageToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
			this->segmentationToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
			this->startToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
			this->stopToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
			this->helpToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
			this->aboutToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
			this->saveFileDialog = (gcnew System::Windows::Forms::SaveFileDialog());
			this->groupBox_Methods = (gcnew System::Windows::Forms::GroupBox());
			this->label_Max_Iterations = (gcnew System::Windows::Forms::Label());
			this->label_Clusters = (gcnew System::Windows::Forms::Label());
			this->numericUpDown_Clusters = (gcnew System::Windows::Forms::NumericUpDown());
			this->label_Methods_Type = (gcnew System::Windows::Forms::Label());
			this->comboBox_Method_Type = (gcnew System::Windows::Forms::ComboBox());
			this->numericUpDown_threshold_1 = (gcnew System::Windows::Forms::NumericUpDown());
			this->numericUpDown_threshold_2 = (gcnew System::Windows::Forms::NumericUpDown());
			this->comboBox_Methods = (gcnew System::Windows::Forms::ComboBox());
			this->checkBox_Treshold = (gcnew System::Windows::Forms::CheckBox());
			this->groupBox_Webcam = (gcnew System::Windows::Forms::GroupBox());
			this->label_Webcam_interval = (gcnew System::Windows::Forms::Label());
			this->button_WebcamIntervalMinus = (gcnew System::Windows::Forms::Button());
			this->button_WebcamIntervalPlus = (gcnew System::Windows::Forms::Button());
			this->button_Webcam_Single = (gcnew System::Windows::Forms::Button());
			this->comboBox_Webcam_device = (gcnew System::Windows::Forms::ComboBox());
			this->timer_Time = (gcnew System::Windows::Forms::Timer(this->components));
			this->groupBox_ImageAdjust = (gcnew System::Windows::Forms::GroupBox());
			this->numericUpDown_adjustTreshold = (gcnew System::Windows::Forms::NumericUpDown());
			this->checkBox_Negative = (gcnew System::Windows::Forms::CheckBox());
			this->backgroundWorker_Webcam = (gcnew System::ComponentModel::BackgroundWorker());
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->pictureBox_Input))->BeginInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->pictureBox_Output))->BeginInit();
			this->groupBox_CPU_CUDA_Processor->SuspendLayout();
			this->groupBox_GPU_select->SuspendLayout();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->numericUpDown_CUDA_threads))->BeginInit();
			this->statusStrip->SuspendLayout();
			this->groupBox_CPU_Info->SuspendLayout();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->numericUpDown_CPU_Thrads))->BeginInit();
			this->tableLayoutPanel->SuspendLayout();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->numericUpDown_WebcamInterval))->BeginInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->numericUpDown_Iterations))->BeginInit();
			this->menuStrip->SuspendLayout();
			this->groupBox_Methods->SuspendLayout();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->numericUpDown_Clusters))->BeginInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->numericUpDown_threshold_1))->BeginInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->numericUpDown_threshold_2))->BeginInit();
			this->groupBox_Webcam->SuspendLayout();
			this->groupBox_ImageAdjust->SuspendLayout();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->numericUpDown_adjustTreshold))->BeginInit();
			this->SuspendLayout();
			// 
			// pictureBox_Input
			// 
			this->pictureBox_Input->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom)
				| System::Windows::Forms::AnchorStyles::Left)
				| System::Windows::Forms::AnchorStyles::Right));
			this->pictureBox_Input->BackgroundImageLayout = System::Windows::Forms::ImageLayout::Zoom;
			this->pictureBox_Input->BorderStyle = System::Windows::Forms::BorderStyle::FixedSingle;
			this->pictureBox_Input->Location = System::Drawing::Point(3, 23);
			this->pictureBox_Input->Name = L"pictureBox_Input";
			this->pictureBox_Input->Size = System::Drawing::Size(469, 398);
			this->pictureBox_Input->SizeMode = System::Windows::Forms::PictureBoxSizeMode::Zoom;
			this->pictureBox_Input->TabIndex = 2;
			this->pictureBox_Input->TabStop = false;
			// 
			// pictureBox_Output
			// 
			this->pictureBox_Output->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom)
				| System::Windows::Forms::AnchorStyles::Left)
				| System::Windows::Forms::AnchorStyles::Right));
			this->pictureBox_Output->BorderStyle = System::Windows::Forms::BorderStyle::FixedSingle;
			this->pictureBox_Output->Location = System::Drawing::Point(478, 23);
			this->pictureBox_Output->Name = L"pictureBox_Output";
			this->pictureBox_Output->Size = System::Drawing::Size(469, 398);
			this->pictureBox_Output->SizeMode = System::Windows::Forms::PictureBoxSizeMode::Zoom;
			this->pictureBox_Output->TabIndex = 3;
			this->pictureBox_Output->TabStop = false;
			// 
			// groupBox_CPU_CUDA_Processor
			// 
			this->groupBox_CPU_CUDA_Processor->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Bottom | System::Windows::Forms::AnchorStyles::Left));
			this->groupBox_CPU_CUDA_Processor->Controls->Add(this->radioButton_CUDA);
			this->groupBox_CPU_CUDA_Processor->Controls->Add(this->radioButton_CPU);
			this->groupBox_CPU_CUDA_Processor->Location = System::Drawing::Point(12, 458);
			this->groupBox_CPU_CUDA_Processor->Name = L"groupBox_CPU_CUDA_Processor";
			this->groupBox_CPU_CUDA_Processor->Size = System::Drawing::Size(141, 92);
			this->groupBox_CPU_CUDA_Processor->TabIndex = 5;
			this->groupBox_CPU_CUDA_Processor->TabStop = false;
			this->groupBox_CPU_CUDA_Processor->Text = L"Segmentation Processor";
			// 
			// radioButton_CUDA
			// 
			this->radioButton_CUDA->AutoSize = true;
			this->radioButton_CUDA->Location = System::Drawing::Point(7, 43);
			this->radioButton_CUDA->Name = L"radioButton_CUDA";
			this->radioButton_CUDA->Size = System::Drawing::Size(94, 17);
			this->radioButton_CUDA->TabIndex = 1;
			this->radioButton_CUDA->Text = L"NVIDIA CUDA";
			this->radioButton_CUDA->UseVisualStyleBackColor = true;
			this->radioButton_CUDA->Click += gcnew System::EventHandler(this, &MyForm::radioButton_CUDA_Click);
			// 
			// radioButton_CPU
			// 
			this->radioButton_CPU->AutoSize = true;
			this->radioButton_CPU->Checked = true;
			this->radioButton_CPU->Location = System::Drawing::Point(7, 20);
			this->radioButton_CPU->Name = L"radioButton_CPU";
			this->radioButton_CPU->Size = System::Drawing::Size(47, 17);
			this->radioButton_CPU->TabIndex = 0;
			this->radioButton_CPU->TabStop = true;
			this->radioButton_CPU->Text = L"CPU";
			this->radioButton_CPU->UseVisualStyleBackColor = true;
			this->radioButton_CPU->Click += gcnew System::EventHandler(this, &MyForm::radioButton_CPU_Click);
			// 
			// openFileDialog
			// 
			this->openFileDialog->AddExtension = false;
			this->openFileDialog->Filter = L"Image Files(*.BMP;*.JPG;*.PNG;*.GIF;*.TIFF)|*.bmp;*.jpg;*.png;*.gif;*.tiff|All fi"
				L"les (*.*)|*.*";
			this->openFileDialog->Title = L"Select an image File";
			// 
			// label_InputImage
			// 
			this->label_InputImage->AutoSize = true;
			this->label_InputImage->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 12.25F));
			this->label_InputImage->Location = System::Drawing::Point(3, 0);
			this->label_InputImage->Name = L"label_InputImage";
			this->label_InputImage->Size = System::Drawing::Size(95, 20);
			this->label_InputImage->TabIndex = 7;
			this->label_InputImage->Text = L"Input Image";
			// 
			// label_OutputImage
			// 
			this->label_OutputImage->AutoSize = true;
			this->label_OutputImage->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 12.25F));
			this->label_OutputImage->Location = System::Drawing::Point(478, 0);
			this->label_OutputImage->Name = L"label_OutputImage";
			this->label_OutputImage->Size = System::Drawing::Size(143, 20);
			this->label_OutputImage->TabIndex = 8;
			this->label_OutputImage->Text = L"Segmented Image";
			// 
			// comboBoxCUDASelect
			// 
			this->comboBoxCUDASelect->DropDownStyle = System::Windows::Forms::ComboBoxStyle::DropDownList;
			this->comboBoxCUDASelect->FormattingEnabled = true;
			this->comboBoxCUDASelect->ImeMode = System::Windows::Forms::ImeMode::NoControl;
			this->comboBoxCUDASelect->Location = System::Drawing::Point(6, 20);
			this->comboBoxCUDASelect->Name = L"comboBoxCUDASelect";
			this->comboBoxCUDASelect->Size = System::Drawing::Size(241, 21);
			this->comboBoxCUDASelect->TabIndex = 6;
			this->comboBoxCUDASelect->SelectedIndexChanged += gcnew System::EventHandler(this, &MyForm::comboBoxCUDASelect_SelectedIndexChanged);
			// 
			// groupBox_GPU_select
			// 
			this->groupBox_GPU_select->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Bottom | System::Windows::Forms::AnchorStyles::Left));
			this->groupBox_GPU_select->Controls->Add(this->label_CUDA_threads);
			this->groupBox_GPU_select->Controls->Add(this->numericUpDown_CUDA_threads);
			this->groupBox_GPU_select->Controls->Add(this->button_GPU_info);
			this->groupBox_GPU_select->Controls->Add(this->comboBoxCUDASelect);
			this->groupBox_GPU_select->Location = System::Drawing::Point(159, 458);
			this->groupBox_GPU_select->Name = L"groupBox_GPU_select";
			this->groupBox_GPU_select->Size = System::Drawing::Size(253, 92);
			this->groupBox_GPU_select->TabIndex = 13;
			this->groupBox_GPU_select->TabStop = false;
			this->groupBox_GPU_select->Text = L"Select GPU Device";
			// 
			// label_CUDA_threads
			// 
			this->label_CUDA_threads->AutoSize = true;
			this->label_CUDA_threads->Location = System::Drawing::Point(6, 52);
			this->label_CUDA_threads->Name = L"label_CUDA_threads";
			this->label_CUDA_threads->Size = System::Drawing::Size(84, 13);
			this->label_CUDA_threads->TabIndex = 17;
			this->label_CUDA_threads->Text = L"Threads / Block";
			// 
			// numericUpDown_CUDA_threads
			// 
			this->numericUpDown_CUDA_threads->Location = System::Drawing::Point(92, 49);
			this->numericUpDown_CUDA_threads->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) { 1024, 0, 0, 0 });
			this->numericUpDown_CUDA_threads->Minimum = System::Decimal(gcnew cli::array< System::Int32 >(4) { 1, 0, 0, 0 });
			this->numericUpDown_CUDA_threads->Name = L"numericUpDown_CUDA_threads";
			this->numericUpDown_CUDA_threads->Size = System::Drawing::Size(44, 20);
			this->numericUpDown_CUDA_threads->TabIndex = 7;
			this->numericUpDown_CUDA_threads->Value = System::Decimal(gcnew cli::array< System::Int32 >(4) { 256, 0, 0, 0 });
			// 
			// button_GPU_info
			// 
			this->button_GPU_info->Location = System::Drawing::Point(142, 47);
			this->button_GPU_info->Name = L"button_GPU_info";
			this->button_GPU_info->Size = System::Drawing::Size(105, 23);
			this->button_GPU_info->TabIndex = 10;
			this->button_GPU_info->Text = L"Get GPU Info";
			this->button_GPU_info->UseVisualStyleBackColor = true;
			this->button_GPU_info->Click += gcnew System::EventHandler(this, &MyForm::button_GPU_info_Click);
			// 
			// statusStrip
			// 
			this->statusStrip->Items->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^  >(10) {
				this->label_CUDAdevices,
					this->label_CUDAdevices_Num, this->label_CaptureDevices, this->label_CaptureDevices_Num, this->label_CPU_Time, this->label_CUDA_Time,
					this->label_OpenCL_Time, this->toolStripStatusLabel_Iterations, this->toolStripStatusLabel_spring, this->toolStripStatusLabel_Time
			});
			this->statusStrip->Location = System::Drawing::Point(0, 552);
			this->statusStrip->Name = L"statusStrip";
			this->statusStrip->Size = System::Drawing::Size(974, 24);
			this->statusStrip->TabIndex = 14;
			this->statusStrip->Text = L"statusStrip1";
			// 
			// label_CUDAdevices
			// 
			this->label_CUDAdevices->Name = L"label_CUDAdevices";
			this->label_CUDAdevices->Size = System::Drawing::Size(133, 19);
			this->label_CUDAdevices->Text = L"CUDA devices detected:";
			// 
			// label_CUDAdevices_Num
			// 
			this->label_CUDAdevices_Num->Name = L"label_CUDAdevices_Num";
			this->label_CUDAdevices_Num->Size = System::Drawing::Size(13, 19);
			this->label_CUDAdevices_Num->Text = L"0";
			// 
			// label_CaptureDevices
			// 
			this->label_CaptureDevices->BorderSides = System::Windows::Forms::ToolStripStatusLabelBorderSides::Left;
			this->label_CaptureDevices->Name = L"label_CaptureDevices";
			this->label_CaptureDevices->Size = System::Drawing::Size(147, 19);
			this->label_CaptureDevices->Text = L"Capture devices detected:";
			this->label_CaptureDevices->Visible = false;
			// 
			// label_CaptureDevices_Num
			// 
			this->label_CaptureDevices_Num->Name = L"label_CaptureDevices_Num";
			this->label_CaptureDevices_Num->Size = System::Drawing::Size(13, 19);
			this->label_CaptureDevices_Num->Text = L"0";
			this->label_CaptureDevices_Num->Visible = false;
			// 
			// label_CPU_Time
			// 
			this->label_CPU_Time->BorderSides = System::Windows::Forms::ToolStripStatusLabelBorderSides::Left;
			this->label_CPU_Time->Name = L"label_CPU_Time";
			this->label_CPU_Time->Size = System::Drawing::Size(70, 19);
			this->label_CPU_Time->Text = L"CPU Time: ";
			this->label_CPU_Time->Visible = false;
			// 
			// label_CUDA_Time
			// 
			this->label_CUDA_Time->BorderSides = System::Windows::Forms::ToolStripStatusLabelBorderSides::Left;
			this->label_CUDA_Time->Name = L"label_CUDA_Time";
			this->label_CUDA_Time->Size = System::Drawing::Size(76, 19);
			this->label_CUDA_Time->Text = L"CUDA Time:";
			this->label_CUDA_Time->Visible = false;
			// 
			// label_OpenCL_Time
			// 
			this->label_OpenCL_Time->BorderSides = System::Windows::Forms::ToolStripStatusLabelBorderSides::Left;
			this->label_OpenCL_Time->Name = L"label_OpenCL_Time";
			this->label_OpenCL_Time->Size = System::Drawing::Size(87, 19);
			this->label_OpenCL_Time->Text = L"OpenCL Time:";
			this->label_OpenCL_Time->Visible = false;
			// 
			// toolStripStatusLabel_Iterations
			// 
			this->toolStripStatusLabel_Iterations->BorderSides = System::Windows::Forms::ToolStripStatusLabelBorderSides::Left;
			this->toolStripStatusLabel_Iterations->Name = L"toolStripStatusLabel_Iterations";
			this->toolStripStatusLabel_Iterations->Size = System::Drawing::Size(66, 19);
			this->toolStripStatusLabel_Iterations->Text = L"Iterations: ";
			this->toolStripStatusLabel_Iterations->Visible = false;
			// 
			// toolStripStatusLabel_spring
			// 
			this->toolStripStatusLabel_spring->Name = L"toolStripStatusLabel_spring";
			this->toolStripStatusLabel_spring->Size = System::Drawing::Size(758, 19);
			this->toolStripStatusLabel_spring->Spring = true;
			// 
			// toolStripStatusLabel_Time
			// 
			this->toolStripStatusLabel_Time->AutoSize = false;
			this->toolStripStatusLabel_Time->BorderSides = static_cast<System::Windows::Forms::ToolStripStatusLabelBorderSides>((System::Windows::Forms::ToolStripStatusLabelBorderSides::Left | System::Windows::Forms::ToolStripStatusLabelBorderSides::Right));
			this->toolStripStatusLabel_Time->Enabled = false;
			this->toolStripStatusLabel_Time->Name = L"toolStripStatusLabel_Time";
			this->toolStripStatusLabel_Time->Size = System::Drawing::Size(55, 19);
			this->toolStripStatusLabel_Time->Text = L"00:00.000";
			this->toolStripStatusLabel_Time->TextAlign = System::Drawing::ContentAlignment::MiddleLeft;
			// 
			// groupBox_CPU_Info
			// 
			this->groupBox_CPU_Info->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Bottom | System::Windows::Forms::AnchorStyles::Left));
			this->groupBox_CPU_Info->Controls->Add(this->label_CPU_Use_Threads);
			this->groupBox_CPU_Info->Controls->Add(this->numericUpDown_CPU_Thrads);
			this->groupBox_CPU_Info->Controls->Add(this->label_CPU_Vendor);
			this->groupBox_CPU_Info->Controls->Add(this->label_CPU_Vendor_text);
			this->groupBox_CPU_Info->Controls->Add(this->label_CPU_Core_Count);
			this->groupBox_CPU_Info->Controls->Add(this->label_CPU_Model_text);
			this->groupBox_CPU_Info->Controls->Add(this->label_CPU_Threads_Count);
			this->groupBox_CPU_Info->Controls->Add(this->label_CPU_Clock);
			this->groupBox_CPU_Info->Controls->Add(this->label_CPU_Model);
			this->groupBox_CPU_Info->Location = System::Drawing::Point(159, 458);
			this->groupBox_CPU_Info->Name = L"groupBox_CPU_Info";
			this->groupBox_CPU_Info->Size = System::Drawing::Size(253, 92);
			this->groupBox_CPU_Info->TabIndex = 14;
			this->groupBox_CPU_Info->TabStop = false;
			this->groupBox_CPU_Info->Text = L"CPU Device";
			// 
			// label_CPU_Use_Threads
			// 
			this->label_CPU_Use_Threads->AutoSize = true;
			this->label_CPU_Use_Threads->Location = System::Drawing::Point(143, 68);
			this->label_CPU_Use_Threads->Name = L"label_CPU_Use_Threads";
			this->label_CPU_Use_Threads->Size = System::Drawing::Size(64, 13);
			this->label_CPU_Use_Threads->TabIndex = 14;
			this->label_CPU_Use_Threads->Text = L"Use threads";
			// 
			// numericUpDown_CPU_Thrads
			// 
			this->numericUpDown_CPU_Thrads->Enabled = false;
			this->numericUpDown_CPU_Thrads->Location = System::Drawing::Point(212, 66);
			this->numericUpDown_CPU_Thrads->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) { 1, 0, 0, 0 });
			this->numericUpDown_CPU_Thrads->Minimum = System::Decimal(gcnew cli::array< System::Int32 >(4) { 1, 0, 0, 0 });
			this->numericUpDown_CPU_Thrads->Name = L"numericUpDown_CPU_Thrads";
			this->numericUpDown_CPU_Thrads->Size = System::Drawing::Size(34, 20);
			this->numericUpDown_CPU_Thrads->TabIndex = 5;
			this->numericUpDown_CPU_Thrads->Value = System::Decimal(gcnew cli::array< System::Int32 >(4) { 1, 0, 0, 0 });
			// 
			// label_CPU_Vendor
			// 
			this->label_CPU_Vendor->AutoSize = true;
			this->label_CPU_Vendor->Location = System::Drawing::Point(116, 45);
			this->label_CPU_Vendor->Name = L"label_CPU_Vendor";
			this->label_CPU_Vendor->Size = System::Drawing::Size(44, 13);
			this->label_CPU_Vendor->TabIndex = 12;
			this->label_CPU_Vendor->Text = L"Vendor:";
			// 
			// label_CPU_Vendor_text
			// 
			this->label_CPU_Vendor_text->Location = System::Drawing::Point(160, 42);
			this->label_CPU_Vendor_text->Name = L"label_CPU_Vendor_text";
			this->label_CPU_Vendor_text->ReadOnly = true;
			this->label_CPU_Vendor_text->Size = System::Drawing::Size(87, 20);
			this->label_CPU_Vendor_text->TabIndex = 4;
			// 
			// label_CPU_Core_Count
			// 
			this->label_CPU_Core_Count->AutoSize = true;
			this->label_CPU_Core_Count->Location = System::Drawing::Point(7, 68);
			this->label_CPU_Core_Count->Name = L"label_CPU_Core_Count";
			this->label_CPU_Core_Count->Size = System::Drawing::Size(49, 13);
			this->label_CPU_Core_Count->TabIndex = 9;
			this->label_CPU_Core_Count->Text = L"Cores:  0";
			// 
			// label_CPU_Model_text
			// 
			this->label_CPU_Model_text->Location = System::Drawing::Point(44, 17);
			this->label_CPU_Model_text->Name = L"label_CPU_Model_text";
			this->label_CPU_Model_text->ReadOnly = true;
			this->label_CPU_Model_text->Size = System::Drawing::Size(203, 20);
			this->label_CPU_Model_text->TabIndex = 3;
			// 
			// label_CPU_Threads_Count
			// 
			this->label_CPU_Threads_Count->AutoSize = true;
			this->label_CPU_Threads_Count->Location = System::Drawing::Point(68, 68);
			this->label_CPU_Threads_Count->Name = L"label_CPU_Threads_Count";
			this->label_CPU_Threads_Count->Size = System::Drawing::Size(61, 13);
			this->label_CPU_Threads_Count->TabIndex = 3;
			this->label_CPU_Threads_Count->Text = L"Threads:  0";
			// 
			// label_CPU_Clock
			// 
			this->label_CPU_Clock->AutoSize = true;
			this->label_CPU_Clock->Location = System::Drawing::Point(7, 45);
			this->label_CPU_Clock->Name = L"label_CPU_Clock";
			this->label_CPU_Clock->Size = System::Drawing::Size(99, 13);
			this->label_CPU_Clock->TabIndex = 1;
			this->label_CPU_Clock->Text = L"Core Clock:  0 MHz";
			// 
			// label_CPU_Model
			// 
			this->label_CPU_Model->AutoSize = true;
			this->label_CPU_Model->Location = System::Drawing::Point(7, 20);
			this->label_CPU_Model->Name = L"label_CPU_Model";
			this->label_CPU_Model->Size = System::Drawing::Size(38, 13);
			this->label_CPU_Model->TabIndex = 0;
			this->label_CPU_Model->Text = L"Name:";
			// 
			// tableLayoutPanel
			// 
			this->tableLayoutPanel->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom)
				| System::Windows::Forms::AnchorStyles::Left)
				| System::Windows::Forms::AnchorStyles::Right));
			this->tableLayoutPanel->ColumnCount = 2;
			this->tableLayoutPanel->ColumnStyles->Add((gcnew System::Windows::Forms::ColumnStyle(System::Windows::Forms::SizeType::Percent,
				50)));
			this->tableLayoutPanel->ColumnStyles->Add((gcnew System::Windows::Forms::ColumnStyle(System::Windows::Forms::SizeType::Percent,
				50)));
			this->tableLayoutPanel->Controls->Add(this->pictureBox_Input, 0, 1);
			this->tableLayoutPanel->Controls->Add(this->label_OutputImage, 1, 0);
			this->tableLayoutPanel->Controls->Add(this->pictureBox_Output, 1, 1);
			this->tableLayoutPanel->Controls->Add(this->label_InputImage, 0, 0);
			this->tableLayoutPanel->Location = System::Drawing::Point(12, 27);
			this->tableLayoutPanel->Name = L"tableLayoutPanel";
			this->tableLayoutPanel->RowCount = 2;
			this->tableLayoutPanel->RowStyles->Add((gcnew System::Windows::Forms::RowStyle(System::Windows::Forms::SizeType::Absolute, 20)));
			this->tableLayoutPanel->RowStyles->Add((gcnew System::Windows::Forms::RowStyle(System::Windows::Forms::SizeType::Percent, 100)));
			this->tableLayoutPanel->Size = System::Drawing::Size(950, 424);
			this->tableLayoutPanel->TabIndex = 16;
			// 
			// button_Webcam_StartStop
			// 
			this->button_Webcam_StartStop->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
			this->button_Webcam_StartStop->Location = System::Drawing::Point(128, 42);
			this->button_Webcam_StartStop->Name = L"button_Webcam_StartStop";
			this->button_Webcam_StartStop->Size = System::Drawing::Size(90, 23);
			this->button_Webcam_StartStop->TabIndex = 17;
			this->button_Webcam_StartStop->Text = L"Start";
			this->toolTip->SetToolTip(this->button_Webcam_StartStop, L"Starts automatic image capture and segmentation");
			this->button_Webcam_StartStop->UseVisualStyleBackColor = true;
			this->button_Webcam_StartStop->Click += gcnew System::EventHandler(this, &MyForm::button_Webcam_StartStop_Click);
			// 
			// numericUpDown_WebcamInterval
			// 
			this->numericUpDown_WebcamInterval->DecimalPlaces = 2;
			this->numericUpDown_WebcamInterval->Increment = System::Decimal(gcnew cli::array< System::Int32 >(4) { 1, 0, 0, 65536 });
			this->numericUpDown_WebcamInterval->Location = System::Drawing::Point(72, 68);
			this->numericUpDown_WebcamInterval->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) { 60, 0, 0, 0 });
			this->numericUpDown_WebcamInterval->Minimum = System::Decimal(gcnew cli::array< System::Int32 >(4) { 1, 0, 0, 65536 });
			this->numericUpDown_WebcamInterval->Name = L"numericUpDown_WebcamInterval";
			this->numericUpDown_WebcamInterval->Size = System::Drawing::Size(50, 20);
			this->numericUpDown_WebcamInterval->TabIndex = 18;
			this->toolTip->SetToolTip(this->numericUpDown_WebcamInterval, L"Describes how often the image from webcam will be loaded");
			this->numericUpDown_WebcamInterval->Value = System::Decimal(gcnew cli::array< System::Int32 >(4) { 5, 0, 0, 65536 });
			this->numericUpDown_WebcamInterval->ValueChanged += gcnew System::EventHandler(this, &MyForm::numericUpDown_WebcamInterval_ValueChanged);
			// 
			// numericUpDown_Iterations
			// 
			this->numericUpDown_Iterations->Location = System::Drawing::Point(107, 67);
			this->numericUpDown_Iterations->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) { 999, 0, 0, 0 });
			this->numericUpDown_Iterations->Name = L"numericUpDown_Iterations";
			this->numericUpDown_Iterations->Size = System::Drawing::Size(43, 20);
			this->numericUpDown_Iterations->TabIndex = 17;
			this->numericUpDown_Iterations->TextAlign = System::Windows::Forms::HorizontalAlignment::Center;
			this->toolTip->SetToolTip(this->numericUpDown_Iterations, L"0 for no limit (NOT RECOMMENDED!)");
			this->numericUpDown_Iterations->Value = System::Decimal(gcnew cli::array< System::Int32 >(4) { 50, 0, 0, 0 });
			// 
			// backgroundWorker
			// 
			this->backgroundWorker->DoWork += gcnew System::ComponentModel::DoWorkEventHandler(this, &MyForm::backgroundWorker_DoWork);
			this->backgroundWorker->RunWorkerCompleted += gcnew System::ComponentModel::RunWorkerCompletedEventHandler(this, &MyForm::backgroundWorker_RunWorkerCompleted);
			// 
			// menuStrip
			// 
			this->menuStrip->Items->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^  >(5) {
				this->fileToolStripMenuItem,
					this->imageToolStripMenuItem, this->inputToolStripMenuItem, this->segmentationToolStripMenuItem, this->helpToolStripMenuItem
			});
			this->menuStrip->Location = System::Drawing::Point(0, 0);
			this->menuStrip->Name = L"menuStrip";
			this->menuStrip->RenderMode = System::Windows::Forms::ToolStripRenderMode::System;
			this->menuStrip->Size = System::Drawing::Size(974, 24);
			this->menuStrip->TabIndex = 17;
			this->menuStrip->Text = L"menuStrip";
			// 
			// fileToolStripMenuItem
			// 
			this->fileToolStripMenuItem->DropDownItems->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^  >(6) {
				this->openToolStripMenuItem,
					this->saveToolStripMenuItem, this->toolStripSeparator2, this->closeToolStripMenuItem, this->toolStripSeparator1, this->exitToolStripMenuItem
			});
			this->fileToolStripMenuItem->Name = L"fileToolStripMenuItem";
			this->fileToolStripMenuItem->Size = System::Drawing::Size(37, 20);
			this->fileToolStripMenuItem->Text = L"&File";
			// 
			// openToolStripMenuItem
			// 
			this->openToolStripMenuItem->Name = L"openToolStripMenuItem";
			this->openToolStripMenuItem->ShortcutKeys = static_cast<System::Windows::Forms::Keys>((System::Windows::Forms::Keys::Control | System::Windows::Forms::Keys::O));
			this->openToolStripMenuItem->Size = System::Drawing::Size(152, 22);
			this->openToolStripMenuItem->Text = L"&Open";
			this->openToolStripMenuItem->ToolTipText = L"Open new image";
			this->openToolStripMenuItem->Click += gcnew System::EventHandler(this, &MyForm::openfileToolStripMenuItem_Click);
			// 
			// saveToolStripMenuItem
			// 
			this->saveToolStripMenuItem->Enabled = false;
			this->saveToolStripMenuItem->Name = L"saveToolStripMenuItem";
			this->saveToolStripMenuItem->ShortcutKeys = static_cast<System::Windows::Forms::Keys>((System::Windows::Forms::Keys::Control | System::Windows::Forms::Keys::S));
			this->saveToolStripMenuItem->Size = System::Drawing::Size(152, 22);
			this->saveToolStripMenuItem->Text = L"&Save as";
			this->saveToolStripMenuItem->ToolTipText = L"Save segmented image";
			this->saveToolStripMenuItem->Click += gcnew System::EventHandler(this, &MyForm::saveToolStripMenuItem_Click);
			// 
			// toolStripSeparator2
			// 
			this->toolStripSeparator2->Name = L"toolStripSeparator2";
			this->toolStripSeparator2->Size = System::Drawing::Size(149, 6);
			// 
			// closeToolStripMenuItem
			// 
			this->closeToolStripMenuItem->Enabled = false;
			this->closeToolStripMenuItem->Name = L"closeToolStripMenuItem";
			this->closeToolStripMenuItem->Size = System::Drawing::Size(152, 22);
			this->closeToolStripMenuItem->Text = L"&Close";
			this->closeToolStripMenuItem->ToolTipText = L"Close currently opened image";
			this->closeToolStripMenuItem->Click += gcnew System::EventHandler(this, &MyForm::closeToolStripMenuItem_Click);
			// 
			// toolStripSeparator1
			// 
			this->toolStripSeparator1->Name = L"toolStripSeparator1";
			this->toolStripSeparator1->Size = System::Drawing::Size(149, 6);
			// 
			// exitToolStripMenuItem
			// 
			this->exitToolStripMenuItem->Name = L"exitToolStripMenuItem";
			this->exitToolStripMenuItem->ShortcutKeys = static_cast<System::Windows::Forms::Keys>((System::Windows::Forms::Keys::Alt | System::Windows::Forms::Keys::F4));
			this->exitToolStripMenuItem->Size = System::Drawing::Size(152, 22);
			this->exitToolStripMenuItem->Text = L"&Exit";
			this->exitToolStripMenuItem->ToolTipText = L"Close application";
			this->exitToolStripMenuItem->Click += gcnew System::EventHandler(this, &MyForm::exitToolStripMenuItem_Click);
			// 
			// imageToolStripMenuItem
			// 
			this->imageToolStripMenuItem->DropDownItems->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^  >(2) {
				this->histogramToolStripMenuItem,
					this->informationToolStripMenuItem
			});
			this->imageToolStripMenuItem->Name = L"imageToolStripMenuItem";
			this->imageToolStripMenuItem->Size = System::Drawing::Size(52, 20);
			this->imageToolStripMenuItem->Text = L"Image";
			this->imageToolStripMenuItem->Visible = false;
			// 
			// histogramToolStripMenuItem
			// 
			this->histogramToolStripMenuItem->Name = L"histogramToolStripMenuItem";
			this->histogramToolStripMenuItem->Size = System::Drawing::Size(137, 22);
			this->histogramToolStripMenuItem->Text = L"Histogram";
			this->histogramToolStripMenuItem->Click += gcnew System::EventHandler(this, &MyForm::showHistogramToolStripMenuItem_Click);
			// 
			// informationToolStripMenuItem
			// 
			this->informationToolStripMenuItem->Name = L"informationToolStripMenuItem";
			this->informationToolStripMenuItem->Size = System::Drawing::Size(137, 22);
			this->informationToolStripMenuItem->Text = L"Information";
			this->informationToolStripMenuItem->Click += gcnew System::EventHandler(this, &MyForm::informationToolStripMenuItem_Click);
			// 
			// inputToolStripMenuItem
			// 
			this->inputToolStripMenuItem->DropDownItems->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^  >(2) {
				this->WebcamFileToolStripMenuItem,
					this->useOutputImageToolStripMenuItem
			});
			this->inputToolStripMenuItem->Name = L"inputToolStripMenuItem";
			this->inputToolStripMenuItem->Size = System::Drawing::Size(47, 20);
			this->inputToolStripMenuItem->Text = L"Input";
			// 
			// WebcamFileToolStripMenuItem
			// 
			this->WebcamFileToolStripMenuItem->CheckOnClick = true;
			this->WebcamFileToolStripMenuItem->Name = L"WebcamFileToolStripMenuItem";
			this->WebcamFileToolStripMenuItem->ShortcutKeys = static_cast<System::Windows::Forms::Keys>((System::Windows::Forms::Keys::Control | System::Windows::Forms::Keys::W));
			this->WebcamFileToolStripMenuItem->Size = System::Drawing::Size(204, 22);
			this->WebcamFileToolStripMenuItem->Text = L"Enable Webcam";
			this->WebcamFileToolStripMenuItem->CheckedChanged += gcnew System::EventHandler(this, &MyForm::WebcamFileToolStripMenuItem_CheckedChanged);
			// 
			// useOutputImageToolStripMenuItem
			// 
			this->useOutputImageToolStripMenuItem->Enabled = false;
			this->useOutputImageToolStripMenuItem->Name = L"useOutputImageToolStripMenuItem";
			this->useOutputImageToolStripMenuItem->Size = System::Drawing::Size(204, 22);
			this->useOutputImageToolStripMenuItem->Text = L"Use Output Image";
			this->useOutputImageToolStripMenuItem->Click += gcnew System::EventHandler(this, &MyForm::useOutputImageToolStripMenuItem_Click);
			// 
			// segmentationToolStripMenuItem
			// 
			this->segmentationToolStripMenuItem->DropDownItems->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^  >(2) {
				this->startToolStripMenuItem,
					this->stopToolStripMenuItem
			});
			this->segmentationToolStripMenuItem->Name = L"segmentationToolStripMenuItem";
			this->segmentationToolStripMenuItem->Size = System::Drawing::Size(93, 20);
			this->segmentationToolStripMenuItem->Text = L"Se&gmentation";
			// 
			// startToolStripMenuItem
			// 
			this->startToolStripMenuItem->Enabled = false;
			this->startToolStripMenuItem->Name = L"startToolStripMenuItem";
			this->startToolStripMenuItem->ShortcutKeys = System::Windows::Forms::Keys::F5;
			this->startToolStripMenuItem->Size = System::Drawing::Size(149, 22);
			this->startToolStripMenuItem->Text = L"Start";
			this->startToolStripMenuItem->Click += gcnew System::EventHandler(this, &MyForm::startToolStripMenuItem_Click);
			// 
			// stopToolStripMenuItem
			// 
			this->stopToolStripMenuItem->Enabled = false;
			this->stopToolStripMenuItem->Name = L"stopToolStripMenuItem";
			this->stopToolStripMenuItem->ShortcutKeys = static_cast<System::Windows::Forms::Keys>((System::Windows::Forms::Keys::Shift | System::Windows::Forms::Keys::F5));
			this->stopToolStripMenuItem->Size = System::Drawing::Size(149, 22);
			this->stopToolStripMenuItem->Text = L"Stop";
			this->stopToolStripMenuItem->Visible = false;
			// 
			// helpToolStripMenuItem
			// 
			this->helpToolStripMenuItem->DropDownItems->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^  >(1) { this->aboutToolStripMenuItem });
			this->helpToolStripMenuItem->Name = L"helpToolStripMenuItem";
			this->helpToolStripMenuItem->Size = System::Drawing::Size(44, 20);
			this->helpToolStripMenuItem->Text = L"&Help";
			// 
			// aboutToolStripMenuItem
			// 
			this->aboutToolStripMenuItem->Name = L"aboutToolStripMenuItem";
			this->aboutToolStripMenuItem->Size = System::Drawing::Size(107, 22);
			this->aboutToolStripMenuItem->Text = L"&About";
			this->aboutToolStripMenuItem->Click += gcnew System::EventHandler(this, &MyForm::aboutToolStripMenuItem_Click);
			// 
			// saveFileDialog
			// 
			this->saveFileDialog->DefaultExt = L"bmp";
			this->saveFileDialog->FileName = L"SegmentedImage";
			this->saveFileDialog->Filter = L"BMP image(*.BMP)|*.bmp|JPG image(*.jpg)|*.jpg|PNG image(*.png)|*.png|GIF image(*."
				L"gif)|*.gif|TIFF image(*.tiff)|*.tiff|All files (*.*)|*.*";
			// 
			// groupBox_Methods
			// 
			this->groupBox_Methods->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Bottom | System::Windows::Forms::AnchorStyles::Left));
			this->groupBox_Methods->Controls->Add(this->label_Max_Iterations);
			this->groupBox_Methods->Controls->Add(this->label_Clusters);
			this->groupBox_Methods->Controls->Add(this->numericUpDown_Clusters);
			this->groupBox_Methods->Controls->Add(this->numericUpDown_Iterations);
			this->groupBox_Methods->Controls->Add(this->label_Methods_Type);
			this->groupBox_Methods->Controls->Add(this->comboBox_Method_Type);
			this->groupBox_Methods->Controls->Add(this->numericUpDown_threshold_1);
			this->groupBox_Methods->Controls->Add(this->numericUpDown_threshold_2);
			this->groupBox_Methods->Controls->Add(this->comboBox_Methods);
			this->groupBox_Methods->Location = System::Drawing::Point(419, 458);
			this->groupBox_Methods->Name = L"groupBox_Methods";
			this->groupBox_Methods->Size = System::Drawing::Size(156, 92);
			this->groupBox_Methods->TabIndex = 18;
			this->groupBox_Methods->TabStop = false;
			this->groupBox_Methods->Text = L"Segmentation Type";
			// 
			// label_Max_Iterations
			// 
			this->label_Max_Iterations->AutoSize = true;
			this->label_Max_Iterations->Location = System::Drawing::Point(6, 70);
			this->label_Max_Iterations->Name = L"label_Max_Iterations";
			this->label_Max_Iterations->Size = System::Drawing::Size(99, 13);
			this->label_Max_Iterations->TabIndex = 19;
			this->label_Max_Iterations->Text = L"Maximum iterations:";
			// 
			// label_Clusters
			// 
			this->label_Clusters->AutoSize = true;
			this->label_Clusters->Location = System::Drawing::Point(6, 45);
			this->label_Clusters->Name = L"label_Clusters";
			this->label_Clusters->Size = System::Drawing::Size(98, 13);
			this->label_Clusters->TabIndex = 18;
			this->label_Clusters->Text = L"Number of clusters:";
			// 
			// numericUpDown_Clusters
			// 
			this->numericUpDown_Clusters->Location = System::Drawing::Point(107, 43);
			this->numericUpDown_Clusters->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) { 99, 0, 0, 0 });
			this->numericUpDown_Clusters->Minimum = System::Decimal(gcnew cli::array< System::Int32 >(4) { 2, 0, 0, 0 });
			this->numericUpDown_Clusters->Name = L"numericUpDown_Clusters";
			this->numericUpDown_Clusters->Size = System::Drawing::Size(43, 20);
			this->numericUpDown_Clusters->TabIndex = 16;
			this->numericUpDown_Clusters->TextAlign = System::Windows::Forms::HorizontalAlignment::Center;
			this->numericUpDown_Clusters->Value = System::Decimal(gcnew cli::array< System::Int32 >(4) { 3, 0, 0, 0 });
			// 
			// label_Methods_Type
			// 
			this->label_Methods_Type->AutoSize = true;
			this->label_Methods_Type->Location = System::Drawing::Point(6, 45);
			this->label_Methods_Type->Name = L"label_Methods_Type";
			this->label_Methods_Type->Size = System::Drawing::Size(34, 13);
			this->label_Methods_Type->TabIndex = 2;
			this->label_Methods_Type->Text = L"Type:";
			// 
			// comboBox_Method_Type
			// 
			this->comboBox_Method_Type->DropDownStyle = System::Windows::Forms::ComboBoxStyle::DropDownList;
			this->comboBox_Method_Type->FormattingEnabled = true;
			this->comboBox_Method_Type->Location = System::Drawing::Point(46, 42);
			this->comboBox_Method_Type->Name = L"comboBox_Method_Type";
			this->comboBox_Method_Type->Size = System::Drawing::Size(104, 21);
			this->comboBox_Method_Type->TabIndex = 12;
			this->comboBox_Method_Type->SelectedIndexChanged += gcnew System::EventHandler(this, &MyForm::comboBox_Method_Type_SelectedIndexChanged);
			// 
			// numericUpDown_threshold_1
			// 
			this->numericUpDown_threshold_1->DecimalPlaces = 2;
			this->numericUpDown_threshold_1->Enabled = false;
			this->numericUpDown_threshold_1->Increment = System::Decimal(gcnew cli::array< System::Int32 >(4) { 1, 0, 0, 65536 });
			this->numericUpDown_threshold_1->Location = System::Drawing::Point(107, 67);
			this->numericUpDown_threshold_1->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) { 1, 0, 0, 0 });
			this->numericUpDown_threshold_1->Name = L"numericUpDown_threshold_1";
			this->numericUpDown_threshold_1->Size = System::Drawing::Size(43, 20);
			this->numericUpDown_threshold_1->TabIndex = 14;
			this->numericUpDown_threshold_1->Value = System::Decimal(gcnew cli::array< System::Int32 >(4) { 2, 0, 0, 65536 });
			this->numericUpDown_threshold_1->ValueChanged += gcnew System::EventHandler(this, &MyForm::numericUpDown_threshold_1_ValueChanged);
			// 
			// numericUpDown_threshold_2
			// 
			this->numericUpDown_threshold_2->DecimalPlaces = 2;
			this->numericUpDown_threshold_2->Increment = System::Decimal(gcnew cli::array< System::Int32 >(4) { 1, 0, 0, 65536 });
			this->numericUpDown_threshold_2->Location = System::Drawing::Point(58, 67);
			this->numericUpDown_threshold_2->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) { 1, 0, 0, 0 });
			this->numericUpDown_threshold_2->Name = L"numericUpDown_threshold_2";
			this->numericUpDown_threshold_2->Size = System::Drawing::Size(43, 20);
			this->numericUpDown_threshold_2->TabIndex = 15;
			this->numericUpDown_threshold_2->Value = System::Decimal(gcnew cli::array< System::Int32 >(4) { 2, 0, 0, 65536 });
			this->numericUpDown_threshold_2->Visible = false;
			this->numericUpDown_threshold_2->ValueChanged += gcnew System::EventHandler(this, &MyForm::numericUpDown_threshold_2_ValueChanged);
			// 
			// comboBox_Methods
			// 
			this->comboBox_Methods->DropDownStyle = System::Windows::Forms::ComboBoxStyle::DropDownList;
			this->comboBox_Methods->FormattingEnabled = true;
			this->comboBox_Methods->Items->AddRange(gcnew cli::array< System::Object^  >(4) {
				L"Edge Detection", L"Tresholding", L"K-Means Clustering",
					L"Grayscale"
			});
			this->comboBox_Methods->Location = System::Drawing::Point(7, 17);
			this->comboBox_Methods->Name = L"comboBox_Methods";
			this->comboBox_Methods->Size = System::Drawing::Size(143, 21);
			this->comboBox_Methods->TabIndex = 11;
			this->comboBox_Methods->SelectedIndexChanged += gcnew System::EventHandler(this, &MyForm::comboBox_Methods_SelectedIndexChanged);
			// 
			// checkBox_Treshold
			// 
			this->checkBox_Treshold->AutoSize = true;
			this->checkBox_Treshold->Location = System::Drawing::Point(6, 43);
			this->checkBox_Treshold->Name = L"checkBox_Treshold";
			this->checkBox_Treshold->Size = System::Drawing::Size(73, 17);
			this->checkBox_Treshold->TabIndex = 14;
			this->checkBox_Treshold->Text = L"Threshold";
			this->checkBox_Treshold->UseVisualStyleBackColor = true;
			this->checkBox_Treshold->CheckedChanged += gcnew System::EventHandler(this, &MyForm::checkBox_Treshold_CheckedChanged);
			// 
			// groupBox_Webcam
			// 
			this->groupBox_Webcam->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Bottom | System::Windows::Forms::AnchorStyles::Left));
			this->groupBox_Webcam->Controls->Add(this->label_Webcam_interval);
			this->groupBox_Webcam->Controls->Add(this->numericUpDown_WebcamInterval);
			this->groupBox_Webcam->Controls->Add(this->button_WebcamIntervalMinus);
			this->groupBox_Webcam->Controls->Add(this->button_WebcamIntervalPlus);
			this->groupBox_Webcam->Controls->Add(this->button_Webcam_Single);
			this->groupBox_Webcam->Controls->Add(this->button_Webcam_StartStop);
			this->groupBox_Webcam->Controls->Add(this->comboBox_Webcam_device);
			this->groupBox_Webcam->Enabled = false;
			this->groupBox_Webcam->Location = System::Drawing::Point(737, 458);
			this->groupBox_Webcam->Name = L"groupBox_Webcam";
			this->groupBox_Webcam->Size = System::Drawing::Size(225, 92);
			this->groupBox_Webcam->TabIndex = 19;
			this->groupBox_Webcam->TabStop = false;
			this->groupBox_Webcam->Text = L"Webcam";
			// 
			// label_Webcam_interval
			// 
			this->label_Webcam_interval->AutoSize = true;
			this->label_Webcam_interval->Location = System::Drawing::Point(7, 71);
			this->label_Webcam_interval->Name = L"label_Webcam_interval";
			this->label_Webcam_interval->Size = System::Drawing::Size(65, 13);
			this->label_Webcam_interval->TabIndex = 6;
			this->label_Webcam_interval->Text = L"Interval ( s ):";
			// 
			// button_WebcamIntervalMinus
			// 
			this->button_WebcamIntervalMinus->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
			this->button_WebcamIntervalMinus->Location = System::Drawing::Point(128, 67);
			this->button_WebcamIntervalMinus->Name = L"button_WebcamIntervalMinus";
			this->button_WebcamIntervalMinus->Size = System::Drawing::Size(42, 22);
			this->button_WebcamIntervalMinus->TabIndex = 19;
			this->button_WebcamIntervalMinus->Text = L"-0,5";
			this->button_WebcamIntervalMinus->UseVisualStyleBackColor = true;
			this->button_WebcamIntervalMinus->Click += gcnew System::EventHandler(this, &MyForm::button_WebcamIntervalMinus_Click);
			// 
			// button_WebcamIntervalPlus
			// 
			this->button_WebcamIntervalPlus->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Right));
			this->button_WebcamIntervalPlus->Location = System::Drawing::Point(176, 67);
			this->button_WebcamIntervalPlus->Name = L"button_WebcamIntervalPlus";
			this->button_WebcamIntervalPlus->Size = System::Drawing::Size(42, 22);
			this->button_WebcamIntervalPlus->TabIndex = 20;
			this->button_WebcamIntervalPlus->Text = L"+0,5";
			this->button_WebcamIntervalPlus->UseVisualStyleBackColor = true;
			this->button_WebcamIntervalPlus->Click += gcnew System::EventHandler(this, &MyForm::button_WebcamIntervalPlus_Click);
			// 
			// button_Webcam_Single
			// 
			this->button_Webcam_Single->Location = System::Drawing::Point(7, 42);
			this->button_Webcam_Single->Name = L"button_Webcam_Single";
			this->button_Webcam_Single->Size = System::Drawing::Size(115, 23);
			this->button_Webcam_Single->TabIndex = 16;
			this->button_Webcam_Single->Text = L"Get Frame";
			this->button_Webcam_Single->UseVisualStyleBackColor = true;
			this->button_Webcam_Single->Click += gcnew System::EventHandler(this, &MyForm::button_Webcam_Single_Click);
			// 
			// comboBox_Webcam_device
			// 
			this->comboBox_Webcam_device->Anchor = static_cast<System::Windows::Forms::AnchorStyles>(((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Left)
				| System::Windows::Forms::AnchorStyles::Right));
			this->comboBox_Webcam_device->DropDownStyle = System::Windows::Forms::ComboBoxStyle::DropDownList;
			this->comboBox_Webcam_device->Enabled = false;
			this->comboBox_Webcam_device->FormattingEnabled = true;
			this->comboBox_Webcam_device->Location = System::Drawing::Point(7, 17);
			this->comboBox_Webcam_device->Name = L"comboBox_Webcam_device";
			this->comboBox_Webcam_device->Size = System::Drawing::Size(212, 21);
			this->comboBox_Webcam_device->TabIndex = 15;
			// 
			// timer_Time
			// 
			this->timer_Time->Interval = 10;
			this->timer_Time->Tick += gcnew System::EventHandler(this, &MyForm::timer_Time_Tick);
			// 
			// groupBox_ImageAdjust
			// 
			this->groupBox_ImageAdjust->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((System::Windows::Forms::AnchorStyles::Bottom | System::Windows::Forms::AnchorStyles::Left));
			this->groupBox_ImageAdjust->Controls->Add(this->numericUpDown_adjustTreshold);
			this->groupBox_ImageAdjust->Controls->Add(this->checkBox_Negative);
			this->groupBox_ImageAdjust->Controls->Add(this->checkBox_Treshold);
			this->groupBox_ImageAdjust->Location = System::Drawing::Point(581, 458);
			this->groupBox_ImageAdjust->Name = L"groupBox_ImageAdjust";
			this->groupBox_ImageAdjust->Size = System::Drawing::Size(150, 92);
			this->groupBox_ImageAdjust->TabIndex = 20;
			this->groupBox_ImageAdjust->TabStop = false;
			this->groupBox_ImageAdjust->Text = L"Image Adjustments";
			// 
			// numericUpDown_adjustTreshold
			// 
			this->numericUpDown_adjustTreshold->DecimalPlaces = 2;
			this->numericUpDown_adjustTreshold->Enabled = false;
			this->numericUpDown_adjustTreshold->Increment = System::Decimal(gcnew cli::array< System::Int32 >(4) { 1, 0, 0, 65536 });
			this->numericUpDown_adjustTreshold->Location = System::Drawing::Point(101, 43);
			this->numericUpDown_adjustTreshold->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) { 1, 0, 0, 0 });
			this->numericUpDown_adjustTreshold->Name = L"numericUpDown_adjustTreshold";
			this->numericUpDown_adjustTreshold->Size = System::Drawing::Size(43, 20);
			this->numericUpDown_adjustTreshold->TabIndex = 15;
			this->numericUpDown_adjustTreshold->Value = System::Decimal(gcnew cli::array< System::Int32 >(4) { 3, 0, 0, 65536 });
			// 
			// checkBox_Negative
			// 
			this->checkBox_Negative->AutoSize = true;
			this->checkBox_Negative->Location = System::Drawing::Point(6, 18);
			this->checkBox_Negative->Name = L"checkBox_Negative";
			this->checkBox_Negative->Size = System::Drawing::Size(69, 17);
			this->checkBox_Negative->TabIndex = 13;
			this->checkBox_Negative->Text = L"Negative";
			this->checkBox_Negative->UseVisualStyleBackColor = true;
			// 
			// backgroundWorker_Webcam
			// 
			this->backgroundWorker_Webcam->WorkerSupportsCancellation = true;
			this->backgroundWorker_Webcam->DoWork += gcnew System::ComponentModel::DoWorkEventHandler(this, &MyForm::backgroundWorker_Webcam_DoWork);
			this->backgroundWorker_Webcam->RunWorkerCompleted += gcnew System::ComponentModel::RunWorkerCompletedEventHandler(this, &MyForm::backgroundWorker_Webcam_RunWorkerCompleted);
			// 
			// MyForm
			// 
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::None;
			this->ClientSize = System::Drawing::Size(974, 576);
			this->Controls->Add(this->groupBox_ImageAdjust);
			this->Controls->Add(this->groupBox_Webcam);
			this->Controls->Add(this->groupBox_Methods);
			this->Controls->Add(this->tableLayoutPanel);
			this->Controls->Add(this->groupBox_CPU_Info);
			this->Controls->Add(this->statusStrip);
			this->Controls->Add(this->menuStrip);
			this->Controls->Add(this->groupBox_GPU_select);
			this->Controls->Add(this->groupBox_CPU_CUDA_Processor);
			this->Icon = (cli::safe_cast<System::Drawing::Icon^>(resources->GetObject(L"$this.Icon")));
			this->MainMenuStrip = this->menuStrip;
			this->MinimumSize = System::Drawing::Size(990, 615);
			this->Name = L"MyForm";
			this->Text = L"Image Segmentation on GPU";
			this->FormClosing += gcnew System::Windows::Forms::FormClosingEventHandler(this, &MyForm::MyForm_FormClosing);
			this->Load += gcnew System::EventHandler(this, &MyForm::MyForm_Load);
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->pictureBox_Input))->EndInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->pictureBox_Output))->EndInit();
			this->groupBox_CPU_CUDA_Processor->ResumeLayout(false);
			this->groupBox_CPU_CUDA_Processor->PerformLayout();
			this->groupBox_GPU_select->ResumeLayout(false);
			this->groupBox_GPU_select->PerformLayout();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->numericUpDown_CUDA_threads))->EndInit();
			this->statusStrip->ResumeLayout(false);
			this->statusStrip->PerformLayout();
			this->groupBox_CPU_Info->ResumeLayout(false);
			this->groupBox_CPU_Info->PerformLayout();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->numericUpDown_CPU_Thrads))->EndInit();
			this->tableLayoutPanel->ResumeLayout(false);
			this->tableLayoutPanel->PerformLayout();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->numericUpDown_WebcamInterval))->EndInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->numericUpDown_Iterations))->EndInit();
			this->menuStrip->ResumeLayout(false);
			this->menuStrip->PerformLayout();
			this->groupBox_Methods->ResumeLayout(false);
			this->groupBox_Methods->PerformLayout();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->numericUpDown_Clusters))->EndInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->numericUpDown_threshold_1))->EndInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->numericUpDown_threshold_2))->EndInit();
			this->groupBox_Webcam->ResumeLayout(false);
			this->groupBox_Webcam->PerformLayout();
			this->groupBox_ImageAdjust->ResumeLayout(false);
			this->groupBox_ImageAdjust->PerformLayout();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->numericUpDown_adjustTreshold))->EndInit();
			this->ResumeLayout(false);
			this->PerformLayout();

		}
#pragma endregion
		//
		// Form Load Function
		//
	private: System::Void MyForm_Load(System::Object^  sender, System::EventArgs^  e)
	{
		// auto select
		this->comboBox_Methods->SelectedIndex = 0;

		// Detect CUDA devices
		this->label_CUDAdevices_Num->Text = cudaInfo::cudaDevCount().ToString();
		if (cudaInfo::cudaDevCount() == 0)
		{
			this->radioButton_CUDA->Enabled = false;
		}

		// Detect and show CPU info, for some reason on some PCs this method doesn't work, in that case just do not display the CPU info
		try
		{
			ManagementClass^ mClass = gcnew ManagementClass("Win32_Processor");
			ManagementObjectCollection^ moCollection = mClass->GetInstances();
			for each (ManagementObject^ mObject in moCollection)
			{
				this->label_CPU_Model_text->Text = mObject->Properties["name"]->Value->ToString();
				this->label_CPU_Vendor_text->Text = mObject->Properties["manufacturer"]->Value->ToString();
				this->label_CPU_Clock->Text = "Core Clock:  " + Convert::ToString(System::Math::Round(Convert::ToDouble(mObject->Properties["currentclockspeed"]->Value->ToString()) / 1000, 2)) + " GHz";
				this->label_CPU_Core_Count->Text = "Cores:  " + mObject->Properties["numberofcores"]->Value;
				this->label_CPU_Threads_Count->Text = "Threads:  " + mObject->Properties["numberoflogicalprocessors"]->Value;
				this->numericUpDown_CPU_Thrads->Maximum = Convert::ToInt16(mObject->Properties["numberoflogicalprocessors"]->Value);
				if (Convert::ToInt16(mObject->Properties["numberoflogicalprocessors"]->Value) > 1)
				{
					this->numericUpDown_CPU_Thrads->Enabled = true;
					this->numericUpDown_CPU_Thrads->Value = Convert::ToInt16(mObject->Properties["numberoflogicalprocessors"]->Value);
				}
			}
		}
		catch (...)
		{
			this->label_CPU_Clock->Text = "Could not detect CPU information!";
			this->label_CPU_Core_Count->Visible = false;
			this->label_CPU_Threads_Count->Visible = false;
			this->label_CPU_Model->Visible = false;
			this->label_CPU_Model_text->Visible = false;
			this->label_CPU_Vendor->Visible = false;
			this->label_CPU_Vendor_text->Visible = false;
			this->label_CPU_Use_Threads->Visible = false;
			this->numericUpDown_CPU_Thrads->Visible = false;
		}
	}

	//
	// ToolstripMenu Functions
	//
	// Open File function
	private: System::Void openfileToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e)
	{
		// opening image file and showing it in pictureBox
		if (this->openFileDialog->ShowDialog() == System::Windows::Forms::DialogResult::OK)
		{
			try
			{
				ClearPictureBoxes();
				bmpIn = gcnew Bitmap(this->openFileDialog->FileName);
				this->pictureBox_Input->Image = bmpIn;

				if (this->pictureBox_Input->Image)
				{
					this->startToolStripMenuItem->Enabled = true;
					this->closeToolStripMenuItem->Enabled = true;
					this->imageToolStripMenuItem->Visible = true;
					this->label_CPU_Time->Visible = false;
					this->label_CUDA_Time->Visible = false;
					this->toolStripStatusLabel_Time->Text = "00:00.000";
				}
			}
			catch (System::Exception^ except)
			{
				// using second form as custom messagebox with window for exception code
				MyFormError^ ErrBox = gcnew MyFormError();
				ErrBox->titleText = "ERROR!";
				ErrBox->descriptionText = "This file could not be opened!";
				ErrBox->exceptionText = except->ToString();
				ErrBox->Buttons = System::Windows::Forms::MessageBoxButtons::RetryCancel;
				ErrBox->dlgIcon = System::Drawing::SystemIcons::Error->ToBitmap();

				// if dialog result equals Retry, OpenfileDialog is open again
				if (ErrBox->ShowDialog() == System::Windows::Forms::DialogResult::Retry)
				{
					this->openToolStripMenuItem->PerformClick();
				}
				// run garbage collector
				System::GC::Collect();
			}
		}
	}

			 // Saving output image function
	private: System::Void saveToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e)
	{
		if (this->saveFileDialog->ShowDialog() == System::Windows::Forms::DialogResult::OK)
		{
			try
			{
				switch (this->saveFileDialog->FilterIndex)
				{
				case 1:
					this->bmpOut->Save(this->saveFileDialog->FileName, System::Drawing::Imaging::ImageFormat::Bmp);
					break;
				case 2:
					this->bmpOut->Save(this->saveFileDialog->FileName, System::Drawing::Imaging::ImageFormat::Jpeg);
					break;
				case 3:
					this->bmpOut->Save(this->saveFileDialog->FileName, System::Drawing::Imaging::ImageFormat::Png);
					break;
				case 4:
					this->bmpOut->Save(this->saveFileDialog->FileName, System::Drawing::Imaging::ImageFormat::Gif);
					break;
				case 5:
					this->bmpOut->Save(this->saveFileDialog->FileName, System::Drawing::Imaging::ImageFormat::Tiff);
					break;
				default:
					this->bmpOut->Save(this->saveFileDialog->FileName, System::Drawing::Imaging::ImageFormat::Bmp);
					break;
				}
				this->saveFileDialog->FilterIndex = 1;
				this->saveFileDialog->FileName = "SegmentedImage";
			}
			catch (System::Exception^ except)
			{
				// using second form as custom messagebox with window for exception code
				MyFormError^ ErrBox = gcnew MyFormError();
				ErrBox->titleText = "ERROR!";
				ErrBox->descriptionText = "File could not be saved!";
				ErrBox->exceptionText = except->ToString();
				ErrBox->Buttons = System::Windows::Forms::MessageBoxButtons::RetryCancel;
				ErrBox->dlgIcon = System::Drawing::SystemIcons::Error->ToBitmap();

				// if dialog result equals Retry, OpenfileDialog is open again
				if (ErrBox->ShowDialog() == System::Windows::Forms::DialogResult::Retry)
				{
					this->saveToolStripMenuItem->PerformClick();
				}
				// run garbage collector
				System::GC::Collect();
			}
		}
	}

			 // clearing pictureboxes, free memory and disable menu options
	private: System::Void closeToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e)
	{
		// clear pictureboxes and free memory
		ClearPictureBoxes();
		// disable options available when images are loaded
		this->saveToolStripMenuItem->Enabled = false;
		this->closeToolStripMenuItem->Enabled = false;
		this->startToolStripMenuItem->Enabled = false;
		this->imageToolStripMenuItem->Visible = false;
		this->useOutputImageToolStripMenuItem->Enabled = false;
		this->label_CPU_Time->Visible = false;
		this->label_CUDA_Time->Visible = false;
		this->label_OpenCL_Time->Visible = false;
		this->toolStripStatusLabel_Iterations->Visible = false;
		this->toolStripStatusLabel_Time->Text = "00:00.000";
	}

			 // function for openning histogram of input image
	private: System::Void showHistogramToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e)
	{
		System::Drawing::Rectangle rect = System::Drawing::Rectangle(0, 0, bmpIn->Width, bmpIn->Height);

		// lockPixels method 
		System::Drawing::Imaging::BitmapData^ bmpData = bmpIn->LockBits(rect, System::Drawing::Imaging::ImageLockMode::ReadWrite, bmpIn->PixelFormat);

		// Get the address of the first line.
		IntPtr ptr = bmpData->Scan0;

		// Declare an arrays to hold the data of images
		int bytes = bmpData->Stride * bmpIn->Height;
		array<Byte>^ rgbValues = gcnew array<Byte>(bytes);
		array<Byte, 2>^ grayValues = gcnew array<Byte, 2>(bmpIn->Height, bmpIn->Width);
		array<double>^ histValues = gcnew array<double>(256);

		// Copy the RGB values into the array.
		System::Runtime::InteropServices::Marshal::Copy(ptr, rgbValues, 0, bytes);

		int threads = Convert::ToInt16(this->numericUpDown_CPU_Thrads->Maximum);

		// iterate through image and create 2D grayscale array ready for processing
		ImageProcessingCPU::RGB2Gray(rgbValues, grayValues, bmpIn->Height, bmpIn->Width, bmpData->Stride, threads);

		ImageProcessingCPU::histData(grayValues, histValues);

		bmpIn->UnlockBits(bmpData);

		if (Histogram)
		{
			Histogram->Close();
			System::GC::Collect();
		}
		Histogram = gcnew MyFormHistogram();
		Histogram->histogramValues = histValues;

		Histogram->Show();
		System::GC::Collect();
	}

			 // function for showing information about input image
	private: System::Void informationToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e)
	{
		if (bmpIn)
		{
			// using messagebox for showing information about input file
			MessageBox::Show("Filename:		" + this->openFileDialog->SafeFileName + "\n" +
				"Width:		" + Convert::ToString(bmpIn->Width) + "\n" +
				"Height:		" + Convert::ToString(bmpIn->Height) + "\n" +
				"Resolution:	" + Convert::ToString(System::Math::Round(Convert::ToDouble(bmpIn->Height * bmpIn->Width) / 1000000, 1)) + " MP\n" +
				"Bits per pixel:	" + Convert::ToString(bmpIn->PixelFormat)->Substring(6, 2) + "\n",
				"Information about image", MessageBoxButtons::OK, MessageBoxIcon::Information);
		}
	}

			 // Start image processing
	private: System::Void startToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e)
	{
		if (this->comboBox_Methods->SelectedIndex != 2)
		{
			this->toolStripStatusLabel_Iterations->Visible = false;
		}
		startProcessing();

	}

			 // helper function initiating image processing
	private: System::Void startProcessing()
	{
		values.threshold = this->checkBox_Treshold->Checked;
		values.CPU = this->radioButton_CPU->Checked;
		values.GPU = this->radioButton_CUDA->Checked;
		values.CPUthreads = Convert::ToInt32(this->numericUpDown_CPU_Thrads->Value);
		values.negative = this->checkBox_Negative->Checked;
		values.GPUthreads = Math::Sqrt(Convert::ToInt32(this->numericUpDown_CUDA_threads->Value));
		values.k = Convert::ToInt32(this->numericUpDown_Clusters->Value);
		values.maxIterations = Convert::ToInt32(this->numericUpDown_Iterations->Value);
		values.method = this->comboBox_Methods->SelectedIndex;
		values.type = this->comboBox_Method_Type->SelectedIndex;
		values.threshold1 = Convert::ToDouble(this->numericUpDown_threshold_1->Value);
		values.threshold2 = Convert::ToDouble(this->numericUpDown_threshold_2->Value);
		values.thresholdEdge = Convert::ToDouble(this->numericUpDown_adjustTreshold->Value);
		if (this->radioButton_CUDA->Checked)
		{
			values.selectedGPU = this->comboBoxCUDASelect->SelectedIndex;
		}
		values.webcamDelay = Convert::ToDouble(this->numericUpDown_WebcamInterval->Value);

		backgroundWorker->RunWorkerAsync();
		// clear output image if processing single frame
		if (this->button_Webcam_StartStop->Text == "Start")
		{
			this->pictureBox_Output->Image = nullptr;
		}
		// disable start of processing while it is running
		this->startToolStripMenuItem->Enabled = false;
		// disable all options while processing
		this->groupBox_CPU_CUDA_Processor->Enabled = false;
		this->groupBox_CPU_Info->Enabled = false;
		this->groupBox_GPU_select->Enabled = false;
		this->groupBox_Methods->Enabled = false;
		this->groupBox_ImageAdjust->Enabled = false;

		// creating stopWatch object;
		sWatch = gcnew Stopwatch();
		//get time of start
		sWatch->Start();
		this->timer_Time->Enabled = true;
	}

			 // file input and webcam input toggle
	private: System::Void WebcamFileToolStripMenuItem_CheckedChanged(System::Object^  sender, System::EventArgs^  e)
	{
		if (this->WebcamFileToolStripMenuItem->Checked == true)
		{
			// change menu item text and disable open file option
			this->WebcamFileToolStripMenuItem->Text = "Disable Webcam";
			this->openToolStripMenuItem->Enabled = false;

			// create capture object and check for errors
			camera = gcnew CamCapture();
			if (SUCCEEDED(camera->GetLastError()));
			{
				this->label_CaptureDevices_Num->Text = Convert::ToString(camera->GetCamCount());
				if (camera->GetCamCount() > 0)
				{
					// enable webcam groupbox and statusbar labels
					this->groupBox_Webcam->Enabled = true;
					this->label_CaptureDevices->Visible = true;
					this->label_CaptureDevices_Num->Visible = true;

					// enable comboBox if there is more than 1 capture device
					if (camera->GetCamCount() > 1)
					{
						this->comboBox_Webcam_device->Enabled = true;
					}
					else
					{
						this->comboBox_Webcam_device->Enabled = false;
					}

					// fill comboBox with names of all capture devices
					for (int id = 0; id < camera->GetCamCount(); id++)
					{
						// allocation of memory for friendly name of capture device
						char *camName;
						camName = (char*)malloc(256 * sizeof(char));
						camera->GetCamName(id, camName, 256);
						// check for errors
						if (SUCCEEDED(camera->GetLastError()))
						{
							// add item to comboBox
							this->comboBox_Webcam_device->Items->Add(msclr::interop::marshal_as<System::String^>(camName));
						}
						else
						{
							// if there is some error while getting name of device, replace it with device ID
							this->comboBox_Webcam_device->Items->Add(id);
						}
						free(camName);
					}

					// change selected index from NULL to 0
					this->comboBox_Webcam_device->SelectedIndex = 0;
				}
				else
				{
					// using second form as custom messagebox with window for exception code
					MyFormError^ ErrBox = gcnew MyFormError();
					ErrBox->titleText = "ERROR!";
					ErrBox->descriptionText = "No capture device detected!";
					ErrBox->Buttons = System::Windows::Forms::MessageBoxButtons::OK;
					ErrBox->dlgIcon = System::Drawing::SystemIcons::Error->ToBitmap();
					ErrBox->ShowDialog();

					// disable webcam groupBox
					this->WebcamFileToolStripMenuItem->PerformClick();

					// run garbage collector
					System::GC::Collect();
				}
			}
		}
		else
		{
			// segmentation of webcam images is in progress, stop it
			if (this->button_Webcam_StartStop->Text == "Stop")
			{
				this->button_Webcam_StartStop->PerformClick();
			}

			// if there is anything in comboBox, clear it
			if (this->comboBox_Webcam_device->Items->Count > 0)
			{
				this->comboBox_Webcam_device->Items->Clear();
			}

			this->label_CaptureDevices->Visible = false;
			this->label_CaptureDevices_Num->Visible = false;

			// disable webcam groupbox, change text of menu item and enable open file option
			this->groupBox_Webcam->Enabled = false;
			this->comboBox_Webcam_device->Enabled = false;
			this->WebcamFileToolStripMenuItem->Text = "Enable Webcam";
			this->openToolStripMenuItem->Enabled = true;
		}
	}

			 // option to use output image
	private: System::Void useOutputImageToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e)
	{
		if (bmpOut)
		{
			// creation of rectangle for image cloning
			System::Drawing::Rectangle rect = System::Drawing::Rectangle(0, 0, bmpOut->Width, bmpOut->Height);

			// clone image
			bmpIn = (bmpOut->Clone(rect, System::Drawing::Imaging::PixelFormat::Format24bppRgb));

			//readjust UI
			this->useOutputImageToolStripMenuItem->Enabled = false;
			this->pictureBox_Input->Image = nullptr;
			this->pictureBox_Input->Image = bmpIn;
			this->pictureBox_Output->Image = nullptr;
		}
		System::GC::Collect();
	}

			 // Show About form
	private: System::Void aboutToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e)
	{
		// create, show and delete about box
		MyFormAbout^ AboutBox = gcnew MyFormAbout();
		AboutBox->ShowDialog();
	}

			 // Exit App function
	private: System::Void exitToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e)
	{
		// using second close event for closing application
		MyForm::Close();
	}

			 //
			 // Segmentation options
			 //
			 // UI changes due to need of different controls
	private: System::Void comboBox_Methods_SelectedIndexChanged(System::Object^  sender, System::EventArgs^  e)
	{
		this->comboBox_Method_Type->Items->Clear();
		switch (this->comboBox_Methods->SelectedIndex)
		{
		case 0:
			// fill comboBox with edge detection method types
			this->comboBox_Method_Type->Visible = true;
			this->label_Methods_Type->Visible = true;
			this->comboBox_Method_Type->Items->Add("Sobel");
			this->comboBox_Method_Type->Items->Add("Prewitt");
			this->comboBox_Method_Type->Items->Add("Kirsch");
			this->comboBox_Method_Type->SelectedIndex = 0;
			this->numericUpDown_threshold_1->Visible = false;
			this->numericUpDown_threshold_2->Visible = false;
			this->checkBox_Negative->Enabled = true;
			this->label_Clusters->Visible = false;
			this->label_Max_Iterations->Visible = false;
			this->numericUpDown_Clusters->Visible = false;
			this->numericUpDown_Iterations->Visible = false;
			// set values, maximums and minimums of tresholding numericupdowns
			this->numericUpDown_threshold_2->Maximum = Convert::ToDecimal(1.0);
			this->numericUpDown_threshold_2->Value = Convert::ToDecimal(0.0);
			// show treshold checkbox
			this->checkBox_Treshold->Enabled = true;
			if (this->checkBox_Treshold->Checked == true)
			{
				this->numericUpDown_adjustTreshold->Enabled = true;
			}
			else
			{
				this->numericUpDown_adjustTreshold->Enabled = false;
			}
			break;
		case 1:
			// fill comboBox with tresholding method types
			this->comboBox_Method_Type->Visible = true;
			this->label_Methods_Type->Visible = true;
			this->comboBox_Method_Type->Items->Add("Simple");
			this->comboBox_Method_Type->Items->Add("Dual Binary");
			this->comboBox_Method_Type->Items->Add("Dual Gray");
			this->comboBox_Method_Type->SelectedIndex = 0;
			this->numericUpDown_threshold_1->Enabled = true;
			this->checkBox_Treshold->Enabled = false;
			this->checkBox_Negative->Enabled = true;
			this->numericUpDown_adjustTreshold->Enabled = false;
			this->label_Clusters->Visible = false;
			this->label_Max_Iterations->Visible = false;
			this->numericUpDown_Clusters->Visible = false;
			this->numericUpDown_Iterations->Visible = false;
			break;
		case 2:
			this->comboBox_Method_Type->Visible = false;
			this->label_Methods_Type->Visible = false;
			this->checkBox_Treshold->Enabled = false;
			this->numericUpDown_adjustTreshold->Enabled = false;
			this->numericUpDown_threshold_1->Visible = false;
			this->numericUpDown_threshold_2->Visible = false;
			this->checkBox_Negative->Enabled = false;
			this->label_Clusters->Visible = true;
			this->label_Max_Iterations->Visible = true;
			this->numericUpDown_Clusters->Visible = true;
			this->numericUpDown_Clusters->Value = 3;
			this->numericUpDown_Iterations->Visible = true;
			this->numericUpDown_Iterations->Value = 50;
			break;
		default:
			this->comboBox_Method_Type->Visible = false;
			this->label_Methods_Type->Visible = false;
			this->checkBox_Treshold->Enabled = false;
			this->numericUpDown_adjustTreshold->Enabled = false;
			this->numericUpDown_threshold_1->Visible = false;
			this->numericUpDown_threshold_2->Visible = false;
			this->checkBox_Negative->Enabled = true;
			this->label_Clusters->Visible = false;
			this->label_Max_Iterations->Visible = false;
			this->numericUpDown_Clusters->Visible = false;
			this->numericUpDown_Iterations->Visible = false;
			break;
		}
	}

			 // UI changes due to need of different controls
	private: System::Void comboBox_Method_Type_SelectedIndexChanged(System::Object^  sender, System::EventArgs^  e)
	{
		if (this->comboBox_Methods->SelectedIndex == 1)
		{
			switch (this->comboBox_Method_Type->SelectedIndex)
			{
			case 0:
				this->numericUpDown_threshold_1->Visible = true;
				this->numericUpDown_threshold_2->Visible = false;
				this->numericUpDown_threshold_2->Maximum = Convert::ToDecimal(0.0);
				this->numericUpDown_threshold_1->Maximum = Convert::ToDecimal(1.0);
				this->numericUpDown_threshold_1->Value = Convert::ToDecimal(0.5);
				break;
			case 1: case 2:
				this->numericUpDown_threshold_1->Visible = true;
				this->numericUpDown_threshold_2->Visible = true;
				this->numericUpDown_threshold_1->Minimum = Convert::ToDecimal(0.0);
				this->numericUpDown_threshold_2->Minimum = Convert::ToDecimal(0.0);
				this->numericUpDown_threshold_1->Maximum = Convert::ToDecimal(1.0);
				this->numericUpDown_threshold_2->Maximum = Convert::ToDecimal(1.0);
				this->numericUpDown_threshold_1->Value = Convert::ToDecimal(0.8);
				this->numericUpDown_threshold_2->Value = Convert::ToDecimal(0.2);
				break;
			default:
				break;
			}
		}
	}

			 // protection of going with tresholds over each other
	private: System::Void numericUpDown_threshold_2_ValueChanged(System::Object^  sender, System::EventArgs^  e)
	{
		this->numericUpDown_threshold_1->Minimum = this->numericUpDown_threshold_2->Value;
	}

			 // protection of going with tresholds over each other
	private: System::Void numericUpDown_threshold_1_ValueChanged(System::Object^  sender, System::EventArgs^  e)
	{
		this->numericUpDown_threshold_2->Maximum = this->numericUpDown_threshold_1->Value;
	}

			 // toggle tresholding
	private: System::Void checkBox_Treshold_CheckedChanged(System::Object^  sender, System::EventArgs^  e)
	{
		if (this->checkBox_Treshold->Checked == true)
		{
			this->numericUpDown_adjustTreshold->Enabled = true;
		}
		else
		{
			this->numericUpDown_adjustTreshold->Enabled = false;
		}
	}

			 //
			 // Segmentation processor selection functions
			 //
			 // CUDA select function
	private: System::Void radioButton_CUDA_Click(System::Object^  sender, System::EventArgs^  e)
	{
		this->groupBox_GPU_select->Visible = true;
		this->groupBox_CPU_Info->Visible = false;
		this->comboBoxCUDASelect->Visible = true;
		this->comboBoxCUDASelect->Items->Clear();
		this->label_CUDA_threads->Visible = true;
		this->numericUpDown_CUDA_threads->Visible = true;
		cudaDeviceProp prop;

		// listing all CUDA device names in comboBox
		for (int i = 0; i < cudaInfo::cudaDevCount(); i++)
		{
			cudaGetDeviceProperties(&prop, i);
			this->comboBoxCUDASelect->Items->Add(msclr::interop::marshal_as<System::String^>(prop.name));
		}

		// compute capability 1.x cards had maximum of threads per block 512, since CC 2 the limit is 1024 threads per block
		if (prop.major < 2)
		{
			this->numericUpDown_CUDA_threads->Maximum = 512;
		}

		// Disabling selection in comboBox if there is only 1 item
		if (this->comboBoxCUDASelect->Items->Count == 1)
		{
			this->comboBoxCUDASelect->Enabled = false;
		}
		else
		{
			this->comboBoxCUDASelect->Enabled = true;
		}

		// selecting index 0 in comboBox
		this->comboBoxCUDASelect->SelectedIndex = 0;
	}

			 // CPU select function
	private: System::Void radioButton_CPU_Click(System::Object^  sender, System::EventArgs^  e)
	{
		//show CPU info and hide GPU info
		this->groupBox_GPU_select->Visible = false;
		this->groupBox_CPU_Info->Visible = true;

		// Stops currently running Nvidia CUDA device and frees up memory
		cudaDeviceReset();
	}

			 //
			 // GPU specific functions
			 //
			 // function showing info about selected GPU
	private: System::Void button_GPU_info_Click(System::Object^  sender, System::EventArgs^  e)
	{
		cudaDeviceProp prop;
		cudaGetDeviceProperties(&prop, this->comboBoxCUDASelect->SelectedIndex);

		//messagebox with CUDA device informations
		MessageBox::Show("Compute Capability:		" + prop.major.ToString() + "." + prop.minor.ToString() + "\n" +
			"Multiprocessor count:	" + prop.multiProcessorCount.ToString() + "\n" +
			"CUDA cores:		" + cudaInfo::cudaGetCUDACores(this->comboBoxCUDASelect->SelectedIndex).ToString() + "\n" +
			"Core Clock:		" + (prop.clockRate / 1E6).ToString() + " GHz\n" +
			"GPU Memory:		" + (prop.totalGlobalMem / (pow(1024, 3))).ToString() + " GB\n" +
			"Memory Clock:		" + (prop.memoryClockRate / 1E6).ToString() + " GHz",
			msclr::interop::marshal_as<System::String^>(prop.name), MessageBoxButtons::OK, MessageBoxIcon::Information);
	}

			 // initialize CUDA device after selecting index for faster run of first kernel
	private: System::Void comboBoxCUDASelect_SelectedIndexChanged(System::Object^  sender, System::EventArgs^  e)
	{
		// select CUDA device from comboBox
		cudaSetDevice(this->comboBoxCUDASelect->SelectedIndex);

		// initialize CUDA device with simple command, that actually does nothing, but makes first run of image processing way faster
		cudaFree(0);
	}

			 //
			 // CPU specific function offloading work to another thread, prevents form from not responding state when working
			 //
	private: System::Void backgroundWorker_DoWork(System::Object^  sender, System::ComponentModel::DoWorkEventArgs^  e)
	{
		int iter = 0;
		if (values.CPU == true)
		{
			try
			{
				// creation of rectangle for LockBits method
				System::Drawing::Rectangle rect = System::Drawing::Rectangle(0, 0, bmpIn->Width, bmpIn->Height);

				// clone input bitmap to output bitmap with 24 bpp pixel format
				bmpOut = (bmpIn->Clone(rect, System::Drawing::Imaging::PixelFormat::Format24bppRgb));

				// lockPixels method 
				System::Drawing::Imaging::BitmapData^ bmpData = bmpOut->LockBits(rect, System::Drawing::Imaging::ImageLockMode::ReadWrite, bmpOut->PixelFormat);

				// Get the address of the first line.
				IntPtr ptr = bmpData->Scan0;

				// Declare an arrays to hold the data of images
				int bytes = bmpData->Stride * bmpOut->Height;
				array<Byte>^ rgbValues = gcnew array<Byte>(bytes);
				array<Byte>^ clustered;
				array<Byte, 2>^ grayValues;
				array<Byte, 2>^ outputValues;

				// create kmeans object, no initialization, unless called
				ImageProcessingCPU CPU_Processing;

				// Copy the RGB values into the array.
				System::Runtime::InteropServices::Marshal::Copy(ptr, rgbValues, 0, bytes);

				// Select type of image processing from comboBox
				switch (values.method)
				{
				case 0:		// edge detection

					grayValues = gcnew array<Byte, 2>(bmpOut->Height, bmpOut->Width);
					outputValues = gcnew array<Byte, 2>(bmpOut->Height, bmpOut->Width);
					// iterate through image and create 2D grayscale array ready for processing
					CPU_Processing.RGB2Gray(rgbValues, grayValues, bmpOut->Height, bmpOut->Width, bmpData->Stride, values.CPUthreads);

					// run edge detection function
					CPU_Processing.edgeDetection(grayValues, outputValues, values.type, values.CPUthreads);

					// run tresholding, if enabled
					if (values.threshold == true)
					{
						CPU_Processing.thresholdEdge(outputValues, values.thresholdEdge, values.CPUthreads);
					}

					// run conversion to negative, if enabled
					if (values.negative == true)
					{
						CPU_Processing.negative(outputValues, values.CPUthreads);
					}

					// iterate through image and fill all pixels with new data
					CPU_Processing.Gray2RGB(rgbValues, outputValues, bmpOut->Height, bmpOut->Width, bmpData->Stride, values.CPUthreads);
					break;
				case 1:		// tresholding
					outputValues = gcnew array<Byte, 2>(bmpOut->Height, bmpOut->Width);

					// iterate through image and create 2D grayscale array ready for processing
					CPU_Processing.RGB2Gray(rgbValues, outputValues, bmpOut->Height, bmpOut->Width, bmpData->Stride, values.CPUthreads);

					CPU_Processing.threshold(outputValues, values.threshold1, values.threshold2, values.type, values.CPUthreads);

					// run conversion to negative, if enabled
					if (values.negative == true)
					{
						CPU_Processing.negative(outputValues, values.CPUthreads);
					}

					// iterate through image and fill all pixels with new data
					CPU_Processing.Gray2RGB(rgbValues, outputValues, bmpOut->Height, bmpOut->Width, bmpData->Stride, values.CPUthreads);
					break;
				case 2:
					clustered = gcnew array<Byte>(bytes);

					// starts kmeans clustering
					iterations = CPU_Processing.kmeans(rgbValues, clustered, values.k, values.maxIterations, bmpOut->Height, bmpOut->Width, bmpData->Stride, values.CPUthreads);

					// copys data to output array
					rgbValues = clustered;
					break;
				default:
					outputValues = gcnew array<Byte, 2>(bmpOut->Height, bmpOut->Width);

					// iterate through image and create 2D grayscale array ready for processing
					CPU_Processing.RGB2Gray(rgbValues, outputValues, bmpOut->Height, bmpOut->Width, bmpData->Stride, values.CPUthreads);

					// run conversion to negative, if enabled
					if (values.negative == true)
					{
						CPU_Processing.negative(outputValues, values.CPUthreads);
					}

					// iterate through image and fill all pixels with new data
					CPU_Processing.Gray2RGB(rgbValues, outputValues, bmpOut->Height, bmpOut->Width, bmpData->Stride, values.CPUthreads);
					break;
				}

				// Copy the RGB values back to the bitmap
				System::Runtime::InteropServices::Marshal::Copy(rgbValues, 0, ptr, bytes);

				// Unlock the bits
				bmpOut->UnlockBits(bmpData);
			}
			catch (System::Exception^ except)
			{
				// using second form as custom messagebox with window for exception code
				MyFormError^ ErrBox = gcnew MyFormError();
				ErrBox->titleText = "ERROR!";
				ErrBox->descriptionText = "This file could not be processed!";
				ErrBox->exceptionText = except->ToString();
				ErrBox->Buttons = System::Windows::Forms::MessageBoxButtons::RetryCancel;
				ErrBox->dlgIcon = System::Drawing::SystemIcons::Error->ToBitmap();

				// if dialog result equals Retry, OpenfileDialog is open again
				if (ErrBox->ShowDialog() == System::Windows::Forms::DialogResult::Retry)
				{
					this->startToolStripMenuItem->Enabled = true;
					this->startToolStripMenuItem->PerformClick();
				}
				// run garbage collector
				System::GC::Collect();
			}
		}
		else if (values.GPU == true)
		{
			try
			{
				// creation of rectangle for LockBits method
				System::Drawing::Rectangle rect = System::Drawing::Rectangle(0, 0, bmpIn->Width, bmpIn->Height);

				// clone input bitmap to output bitmap with 24 bpp pixel format
				bmpOut = (bmpIn->Clone(rect, System::Drawing::Imaging::PixelFormat::Format24bppRgb));

				// lockPixels method 
				System::Drawing::Imaging::BitmapData^ bmpData = bmpOut->LockBits(rect, System::Drawing::Imaging::ImageLockMode::ReadWrite, bmpOut->PixelFormat);

				IntPtr ptr = bmpData->Scan0;
				BYTE *rgbValues = (BYTE*)ptr.ToPointer();
				BYTE *img, *gray, *output;
				cudaError_t cudaStatus;
				cudaDeviceProp prop;
				cudaKernelLauncher CUDA;

				cudaGetDeviceProperties(&prop, 0);

				int div = 1, offset = 0;
				unsigned long long bytes = bmpData->Stride * bmpOut->Height;

				// run selected method
				switch (values.method)
				{
				case 0:		// edge detection
					// count how many iterations have to be done to process image
					for (div = 1; div < bmpOut->Height; div++)
					{
						if ((bytes / div) * 2 < prop.totalGlobalMem * 0.8)
						{
							break;
						}
					}
					// memory allocation for selected method
					cudaStatus = cudaMalloc(&img, bmpData->Stride * bmpOut->Height / div * sizeof(BYTE));
					if (cudaStatus != cudaSuccess)
					{
						goto cancel_CUDA;
					}
					cudaStatus = cudaMalloc(&gray, bmpOut->Width * bmpOut->Height / div * sizeof(BYTE));
					if (cudaStatus != cudaSuccess)
					{
						goto cancel_CUDA;
					}
					cudaStatus = cudaMalloc(&output, bmpOut->Width * bmpOut->Height / div * sizeof(BYTE));
					if (cudaStatus != cudaSuccess)
					{
						goto cancel_CUDA;
					}

					// if image is too big, processing will be divided into cycles
					for (int i = 0; i < div; i++)
					{
						offset = bmpData->Stride * bmpOut->Height / div * i;
						cudaStatus = cudaMemcpy(img, rgbValues + offset, bmpData->Stride * bmpOut->Height / div * sizeof(BYTE), cudaMemcpyHostToDevice);
						if (cudaStatus != cudaSuccess)
						{
							goto cancel_CUDA;
						}
						cudaStatus = CUDA.cudaRGB2Gray(img, gray, bmpOut->Height / div, bmpOut->Width, bmpData->Stride, values.GPUthreads);
						if (cudaStatus != cudaSuccess)
						{
							goto cancel_CUDA;
						}

						cudaStatus = CUDA.cudaEdgeDetection(gray, output, bmpOut->Height / div, bmpOut->Width, values.type, values.GPUthreads);
						if (cudaStatus != cudaSuccess)
						{
							goto cancel_CUDA;
						}

						// run tresholding, if enabled
						if (values.threshold == true)
						{
							cudaStatus = CUDA.cudaThresholdEdge(output, bmpOut->Height / div, bmpOut->Width, values.thresholdEdge, values.GPUthreads);
							if (cudaStatus != cudaSuccess)
							{
								goto cancel_CUDA;
							}
						}

						// run conversion to negative, if enabled
						if (values.negative == true)
						{
							cudaStatus = CUDA.cudaNegative(output, bmpOut->Height / div, bmpOut->Width, values.GPUthreads);
							if (cudaStatus != cudaSuccess)
							{
								goto cancel_CUDA;
							}
						}

						cudaStatus = CUDA.cudaGray2RGB(img, output, bmpOut->Height / div, bmpOut->Width, bmpData->Stride, values.GPUthreads);
						if (cudaStatus != cudaSuccess)
						{
							goto cancel_CUDA;
						}
						cudaStatus = cudaMemcpy(rgbValues + offset, img, bmpData->Stride * bmpOut->Height / div * sizeof(BYTE), cudaMemcpyDeviceToHost);
						if (cudaStatus != cudaSuccess)
						{
							goto cancel_CUDA;
						}
					}
					break;
				case 1:		// thresholding
					// count how many iterations have to be done to process image
					for (div = 1; div < bmpOut->Height; div++)
					{
						if ((bytes / div) * 2 < prop.totalGlobalMem * 0.8)
						{
							break;
						}
					}
					// memory allocation for selected method
					cudaStatus = cudaMalloc(&img, bmpData->Stride * bmpOut->Height / div * sizeof(BYTE));
					if (cudaStatus != cudaSuccess)
					{
						goto cancel_CUDA;
					}
					cudaStatus = cudaMalloc(&output, bmpOut->Width * bmpOut->Height / div * sizeof(BYTE));
					if (cudaStatus != cudaSuccess)
					{
						goto cancel_CUDA;
					}

					// if image is too big, processing will be divided into cycles
					for (int i = 0; i < div; i++)
					{
						offset = bmpData->Stride * bmpOut->Height / div * i;
						cudaStatus = cudaMemcpy(img, rgbValues + offset, bmpData->Stride * bmpOut->Height / div * sizeof(BYTE), cudaMemcpyHostToDevice);
						if (cudaStatus != cudaSuccess)
						{
							goto cancel_CUDA;
						}
						cudaStatus = CUDA.cudaRGB2Gray(img, output, bmpOut->Height / div, bmpOut->Width, bmpData->Stride, values.GPUthreads);
						if (cudaStatus != cudaSuccess)
						{
							goto cancel_CUDA;
						}

						cudaStatus = CUDA.cudaThreshold(output, bmpOut->Height / div, bmpOut->Width, values.threshold1, values.threshold2, values.type, values.GPUthreads);
						if (cudaStatus != cudaSuccess)
						{
							goto cancel_CUDA;
						}

						// run conversion to negative, if enabled
						if (values.negative == true)
						{
							cudaStatus = CUDA.cudaNegative(output, bmpOut->Height / div, bmpOut->Width, values.GPUthreads);
							if (cudaStatus != cudaSuccess)
							{
								goto cancel_CUDA;
							}
						}

						cudaStatus = CUDA.cudaGray2RGB(img, output, bmpOut->Height / div, bmpOut->Width, bmpData->Stride, values.GPUthreads);
						if (cudaStatus != cudaSuccess)
						{
							goto cancel_CUDA;
						}
						cudaStatus = cudaMemcpy(rgbValues + offset, img, bmpData->Stride * bmpOut->Height / div * sizeof(BYTE), cudaMemcpyDeviceToHost);
						if (cudaStatus != cudaSuccess)
						{
							goto cancel_CUDA;
						}
					}
					break;
				case 2:	// kmeans clustering
					// count how many iterations have to be done to process image
					for (div = 1; div < bmpOut->Height; div++)
					{
						if ((bytes / div) * 4 < prop.totalGlobalMem * 0.8)
						{
							break;
						}
					}
					cudaStatus = cudaMalloc(&img, bmpData->Stride * bmpOut->Height / div * sizeof(BYTE));
					if (cudaStatus != cudaSuccess)
					{
						goto cancel_CUDA;
					}
					cudaStatus = cudaMalloc(&output, bmpOut->Width * bmpOut->Height / div * sizeof(BYTE));
					if (cudaStatus != cudaSuccess)
					{
						goto cancel_CUDA;
					}

					cudaStatus = CUDA.cudaKmeans(rgbValues, div, values.k, values.maxIterations, &iter, bmpOut->Height, bmpOut->Width, bmpData->Stride, values.GPUthreads);
					if (cudaStatus != cudaSuccess)
					{
						goto cancel_CUDA;
					}

					iterations = iter;

					break;
				default:	// grayscale
					// count how many iterations have to be done to process image
					for (div = 1; div < bmpOut->Height; div++)
					{
						if ((bytes / div) * 2 < prop.totalGlobalMem * 0.8)
						{
							break;
						}
					}
					// memory allocation for selected method
					cudaStatus = cudaMalloc(&img, bmpData->Stride * bmpOut->Height / div * sizeof(BYTE));
					if (cudaStatus != cudaSuccess)
					{
						goto cancel_CUDA;
					}
					cudaStatus = cudaMalloc(&output, bmpOut->Width * bmpOut->Height / div * sizeof(BYTE));
					if (cudaStatus != cudaSuccess)
					{
						goto cancel_CUDA;
					}

					// if image is too big, processing will be divided into cycles
					for (int i = 0; i < div; i++)
					{
						offset = bmpData->Stride * bmpOut->Height / div * i;
						cudaStatus = cudaMemcpy(img, rgbValues + offset, bmpData->Stride * bmpOut->Height / div * sizeof(BYTE), cudaMemcpyHostToDevice);
						if (cudaStatus != cudaSuccess)
						{
							goto cancel_CUDA;
						}
						cudaStatus = CUDA.cudaRGB2Gray(img, output, bmpOut->Height / div, bmpOut->Width, bmpData->Stride, values.GPUthreads);
						if (cudaStatus != cudaSuccess)
						{
							goto cancel_CUDA;
						}

						// run conversion to negative, if enabled
						if (values.negative == true)
						{
							cudaStatus = CUDA.cudaNegative(output, bmpOut->Height / div, bmpOut->Width, values.GPUthreads);
							if (cudaStatus != cudaSuccess)
							{
								goto cancel_CUDA;
							}
						}

						cudaStatus = CUDA.cudaGray2RGB(img, output, bmpOut->Height / div, bmpOut->Width, bmpData->Stride, values.GPUthreads);
						if (cudaStatus != cudaSuccess)
						{
							goto cancel_CUDA;
						}
						cudaStatus = cudaMemcpy(rgbValues + offset, img, bmpData->Stride * bmpOut->Height / div * sizeof(BYTE), cudaMemcpyDeviceToHost);
						if (cudaStatus != cudaSuccess)
						{
							goto cancel_CUDA;
						}
					}
					break;
				}

			cancel_CUDA:
				if (cudaStatus != cudaSuccess)
				{
					// using second form as custom messagebox with window for exception code
					MyFormError^ ErrBox = gcnew MyFormError();
					ErrBox->titleText = "ERROR!";
					ErrBox->descriptionText = "CUDA failed with error code: " + Convert::ToString(cudaStatus);
					ErrBox->exceptionText = msclr::interop::marshal_as<System::String^>(cudaInfo::cudaGetError(cudaStatus));
					ErrBox->Buttons = System::Windows::Forms::MessageBoxButtons::OK;
					ErrBox->dlgIcon = System::Drawing::SystemIcons::Error->ToBitmap();
					ErrBox->ShowDialog();
					// run garbage collector
					System::GC::Collect();
				}
				cudaFree(gray);
				cudaFree(img);
				cudaFree(output);
				// Unlock the bits
				bmpOut->UnlockBits(bmpData);
			}
			catch (System::Exception^ except)
			{
				// using second form as custom messagebox with window for exception code
				MyFormError^ ErrBox = gcnew MyFormError();
				ErrBox->titleText = "ERROR!";
				ErrBox->descriptionText = "This file could not be processed!";
				ErrBox->exceptionText = except->ToString();
				ErrBox->Buttons = System::Windows::Forms::MessageBoxButtons::RetryCancel;
				ErrBox->dlgIcon = System::Drawing::SystemIcons::Error->ToBitmap();

				// if dialog result equals Retry, OpenfileDialog is open again
				if (ErrBox->ShowDialog() == System::Windows::Forms::DialogResult::Retry)
				{
					this->startToolStripMenuItem->Enabled = true;
					this->startToolStripMenuItem->PerformClick();
				}
				// run garbage collector
				System::GC::Collect();
			}
		}
	}

	private: System::Void backgroundWorker_RunWorkerCompleted(System::Object^  sender, System::ComponentModel::RunWorkerCompletedEventArgs^  e)
	{
		// get time of finish
		sWatch->Stop();
		this->timer_Time->Enabled = false;
		// calculate finish time and show it
		char minutes = sWatch->ElapsedMilliseconds / (1000 * 60);
		char seconds = sWatch->ElapsedMilliseconds / 1000 - minutes * 60;
		int miliseconds = (sWatch->ElapsedMilliseconds - seconds * 1000 - minutes * 60 * 1000);

		if (minutes < 10)
		{
			this->toolStripStatusLabel_Time->Text = "0" + Convert::ToString(minutes);
		}
		else
		{
			this->toolStripStatusLabel_Time->Text = Convert::ToString(minutes);
		}

		if (seconds < 10)
		{
			this->toolStripStatusLabel_Time->Text = this->toolStripStatusLabel_Time->Text + ":0" + Convert::ToString(seconds);
		}
		else
		{
			this->toolStripStatusLabel_Time->Text = this->toolStripStatusLabel_Time->Text + ":" + Convert::ToString(seconds);
		}

		if (miliseconds < 100)
		{
			if (miliseconds < 10)
			{
				this->toolStripStatusLabel_Time->Text = this->toolStripStatusLabel_Time->Text + ".00" + Convert::ToString(miliseconds);
			}
			else
			{
				this->toolStripStatusLabel_Time->Text = this->toolStripStatusLabel_Time->Text + ".0" + Convert::ToString(miliseconds);
			}
		}
		else
		{
			this->toolStripStatusLabel_Time->Text = this->toolStripStatusLabel_Time->Text + "." + Convert::ToString(miliseconds);
		}

		if (this->button_Webcam_StartStop->Text == "Start")
		{
			this->pictureBox_Output->Image = bmpOut;
			// enable saving of output image and next round of segmentation
			this->saveToolStripMenuItem->Enabled = true;
			this->startToolStripMenuItem->Enabled = true;
			// enable all settings
			this->groupBox_CPU_CUDA_Processor->Enabled = true;
			this->groupBox_CPU_Info->Enabled = true;
			this->groupBox_GPU_select->Enabled = true;
			this->groupBox_Methods->Enabled = true;
			this->groupBox_ImageAdjust->Enabled = true;

			// show time of conversion in statusStrip
			if (radioButton_CPU->Checked == true)
			{
				this->label_CPU_Time->Visible = true;
				this->label_CPU_Time->Text = "CPU Time: " + this->toolStripStatusLabel_Time->Text;
			}
			else if (radioButton_CUDA->Checked == true)
			{
				this->label_CUDA_Time->Visible = true;
				this->label_CUDA_Time->Text = "CUDA Time: " + this->toolStripStatusLabel_Time->Text;
			}

			// show number of iterations
			if (this->comboBox_Methods->SelectedIndex == 2)
			{
				this->toolStripStatusLabel_Iterations->Visible = true;
				this->toolStripStatusLabel_Iterations->Text = "Iterations: " + Convert::ToString(iterations);
			}

			// run Garbace Collector for freeing up memory after gcnew
			System::GC::Collect();
		}
		else
		{
			System::Drawing::Rectangle rect = System::Drawing::Rectangle(0, 0, bmpOut->Width, bmpOut->Height);
			bmpWebOut = (bmpOut->Clone(rect, System::Drawing::Imaging::PixelFormat::Format24bppRgb));
			this->pictureBox_Output->Image = bmpWebOut;

			// show time of conversion in statusStrip
			if (radioButton_CPU->Checked == true)
			{
				this->label_CPU_Time->Visible = true;
				this->label_CPU_Time->Text = "CPU Time: " + Convert::ToString(Convert::ToDouble(sWatch->ElapsedMilliseconds) / 1000) + " s";
			}
			else if (radioButton_CUDA->Checked == true)
			{
				this->label_CUDA_Time->Visible = true;
				this->label_CUDA_Time->Text = "CUDA Time: " + Convert::ToString(Convert::ToDouble(sWatch->ElapsedMilliseconds) / 1000) + " s";
			}
			if (this->button_Webcam_StartStop->Text == "Stop")
			{
				delete bmpIn;
			}

			// run Garbace Collector for freeing up memory after gcnew
			System::GC::Collect();
		}

		if (this->pictureBox_Output->Image)
		{
			this->useOutputImageToolStripMenuItem->Enabled = true;
		}
	}

	//
	// showing messageBox with exit prompt on closing app
	//
	private: System::Void MyForm_FormClosing(System::Object^  sender, System::Windows::Forms::FormClosingEventArgs^  e)
	{
		// using second form as custom messagebox
		MyFormError^ MsgBox = gcnew MyFormError();
		MsgBox->titleText = "Close Image Segmentation";
		MsgBox->descriptionText = "Do you really want to close this application?";
		MsgBox->Buttons = System::Windows::Forms::MessageBoxButtons::OKCancel;
		MsgBox->dlgIcon = System::Drawing::SystemIcons::Warning->ToBitmap();
		MsgBox->Size = System::Drawing::Size(300, MsgBox->Size.Height);

		// showing messagebox asking for confirmation on closing application
		if (MsgBox->ShowDialog() != System::Windows::Forms::DialogResult::OK)
		{
			e->Cancel = true;
		}
		// run garbage collector
		System::GC::Collect();
		// Needed for Nvidia profiler
		cudaDeviceReset();
	}

	//
	// webcam associated functions
	//
	// interval changed
	private: System::Void numericUpDown_WebcamInterval_ValueChanged(System::Object^  sender, System::EventArgs^  e)
	{
		// disable buttons at limit values
		if (this->numericUpDown_WebcamInterval->Value == this->numericUpDown_WebcamInterval->Maximum)
		{
			this->button_WebcamIntervalPlus->Enabled = false;
			this->button_WebcamIntervalMinus->Enabled = true;
		}
		else if (numericUpDown_WebcamInterval->Value == this->numericUpDown_WebcamInterval->Minimum)
		{
			this->button_WebcamIntervalMinus->Enabled = false;
			this->button_WebcamIntervalPlus->Enabled = true;
		}
		else
		{
			// enable buttons if not at limit values
			if (this->button_WebcamIntervalPlus->Enabled == false)
			{
				this->button_WebcamIntervalPlus->Enabled = true;
			}
			if (this->button_WebcamIntervalMinus->Enabled == false)
			{
				this->button_WebcamIntervalMinus->Enabled = true;
			}
		}

		// change interval value of timer_Time
		values.webcamDelay = Convert::ToDouble(this->numericUpDown_WebcamInterval->Value);
	}

			 // decrease webcam capture interval by 0.5 second
	private: System::Void button_WebcamIntervalMinus_Click(System::Object^  sender, System::EventArgs^  e)
	{
		if (Convert::ToDecimal(Convert::ToDouble(this->numericUpDown_WebcamInterval->Value) - 0.5) < this->numericUpDown_WebcamInterval->Minimum)
		{
			this->numericUpDown_WebcamInterval->Value = this->numericUpDown_WebcamInterval->Minimum;
		}
		else
		{
			this->numericUpDown_WebcamInterval->Value = Convert::ToDecimal(Convert::ToDouble(this->numericUpDown_WebcamInterval->Value) - 0.5);
		}
	}

			 // increase webcam capture interval by 0.5 second
	private: System::Void button_WebcamIntervalPlus_Click(System::Object^  sender, System::EventArgs^  e)
	{
		if (Convert::ToDecimal(Convert::ToDouble(this->numericUpDown_WebcamInterval->Value) + 0.5) > this->numericUpDown_WebcamInterval->Maximum)
		{
			this->numericUpDown_WebcamInterval->Value = this->numericUpDown_WebcamInterval->Maximum;
		}
		else
		{
			this->numericUpDown_WebcamInterval->Value = Convert::ToDecimal(Convert::ToDouble(this->numericUpDown_WebcamInterval->Value) + 0.5);
		}
	}

			 // start segmenting image from camera
	private: System::Void button_Webcam_StartStop_Click(System::Object^  sender, System::EventArgs^  e)
	{
		// Check in which mode is the Start/Stop button
		if (this->button_Webcam_StartStop->Text == "Start")
		{
			this->backgroundWorker_Webcam->RunWorkerAsync();
			// Change functionality of a button
			this->button_Webcam_StartStop->Text = "Stop";
			// clear output picturebox
			this->pictureBox_Output->Image = nullptr;
			// disable start of processing while it is running
			this->startToolStripMenuItem->Enabled = false;
			this->closeToolStripMenuItem->Enabled = false;
			// disable all options while processing
			this->groupBox_CPU_CUDA_Processor->Enabled = false;
			this->groupBox_CPU_Info->Enabled = false;
			this->groupBox_GPU_select->Enabled = false;
			this->groupBox_Methods->Enabled = false;
			this->groupBox_ImageAdjust->Enabled = false;
			this->button_Webcam_Single->Enabled = false;
			this->numericUpDown_Iterations->Maximum = 20;
			this->button_Webcam_Single->Visible = false;
			// prevents crashing during capture
			Form::FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedSingle;
		}
		else if (this->button_Webcam_StartStop->Text == "Stop")
		{
			this->backgroundWorker_Webcam->CancelAsync();
			while (this->backgroundWorker->IsBusy == true)
			{
				Sleep(50);
			}
			// Change functionality of a button
			this->button_Webcam_StartStop->Text = "Start";
			// disable start of processing while it is running
			this->startToolStripMenuItem->Enabled = true;
			this->closeToolStripMenuItem->Enabled = true;
			// disable all options while processing
			this->groupBox_CPU_CUDA_Processor->Enabled = true;
			this->groupBox_CPU_Info->Enabled = true;
			this->groupBox_GPU_select->Enabled = true;
			this->groupBox_Methods->Enabled = true;
			this->groupBox_ImageAdjust->Enabled = true;
			this->button_Webcam_Single->Enabled = true;
			this->numericUpDown_Iterations->Maximum = 999;
			this->button_Webcam_Single->Visible = true;
			// prevents crashing during capture
			Form::FormBorderStyle = System::Windows::Forms::FormBorderStyle::Sizable;
		}
	}

	private: System::Void timer_Time_Tick(System::Object^  sender, System::EventArgs^  e)
	{
		char minutes = sWatch->ElapsedMilliseconds / (1000 * 60);
		char seconds = sWatch->ElapsedMilliseconds / 1000 - minutes * 60;
		int miliseconds = (sWatch->ElapsedMilliseconds - seconds * 1000 - minutes * 60 * 1000);

		if (minutes < 10)
		{
			this->toolStripStatusLabel_Time->Text = "0" + Convert::ToString(minutes);
		}
		else
		{
			this->toolStripStatusLabel_Time->Text = Convert::ToString(minutes);
		}

		if (seconds < 10)
		{
			this->toolStripStatusLabel_Time->Text = this->toolStripStatusLabel_Time->Text + ":0" + Convert::ToString(seconds);
		}
		else
		{
			this->toolStripStatusLabel_Time->Text = this->toolStripStatusLabel_Time->Text + ":" + Convert::ToString(seconds);
		}

		if (miliseconds < 100)
		{
			if (miliseconds < 10)
			{
				this->toolStripStatusLabel_Time->Text = this->toolStripStatusLabel_Time->Text + ".00" + Convert::ToString(miliseconds);
			}
			else
			{
				this->toolStripStatusLabel_Time->Text = this->toolStripStatusLabel_Time->Text + ".0" + Convert::ToString(miliseconds);
			}
		}
		else
		{
			this->toolStripStatusLabel_Time->Text = this->toolStripStatusLabel_Time->Text + "." + Convert::ToString(miliseconds);
		}
	}

	private: System::Void button_Webcam_Single_Click(System::Object^  sender, System::EventArgs^  e)
	{
		cv::VideoCapture cap(this->comboBox_Webcam_device->SelectedIndex);

		cv::Mat frame;

		cap.read(frame);

		bmpIn = gcnew Bitmap(frame.cols, frame.rows, frame.step, System::Drawing::Imaging::PixelFormat::Format24bppRgb, (System::IntPtr)frame.data);

		this->pictureBox_Input->Image = this->pictureBox_Input->Image->FromHbitmap(bmpIn->GetHbitmap());
		// check for loaded image
		if (bmpIn)
		{
			startProcessing();
		}
		if (this->pictureBox_Input->Image)
		{
			this->startToolStripMenuItem->Enabled = true;
			this->startToolStripMenuItem->Visible = true;
		}
	}

	private: System::Void backgroundWorker_Webcam_DoWork(System::Object^  sender, System::ComponentModel::DoWorkEventArgs^  e)
	{
		cv::VideoCapture cap(this->comboBox_Webcam_device->SelectedIndex);

		cv::Mat frame;

		cap.read(frame);

		System::Drawing::Rectangle rect = System::Drawing::Rectangle(0, 0, frame.cols, frame.rows);

		bmpWebIn = gcnew Bitmap(frame.cols, frame.rows, frame.step, System::Drawing::Imaging::PixelFormat::Format24bppRgb, (System::IntPtr)frame.data);

		System::Drawing::Imaging::BitmapData^ bmpData;

		while (true)
		{
			Sleep(values.webcamDelay * 1000);
			if (this->backgroundWorker->IsBusy == false)
			{
				cap.read(frame);

				bmpData = bmpWebIn->LockBits(rect, System::Drawing::Imaging::ImageLockMode::WriteOnly, System::Drawing::Imaging::PixelFormat::Format24bppRgb);

				memcpy(bmpData->Scan0.ToPointer(), frame.data, frame.step * frame.rows * sizeof(BYTE));

				bmpWebIn->UnlockBits(bmpData);

				bmpIn = bmpWebIn->Clone(rect, System::Drawing::Imaging::PixelFormat::Format24bppRgb);

				this->pictureBox_Input->Image = bmpWebIn;
				startProcessing();
				while (this->backgroundWorker->IsBusy == true)
				{
					Sleep(100);
				}

				if (this->backgroundWorker_Webcam->CancellationPending == true)
				{
					e->Cancel = true;
					// fix crashing after stopping capture
					this->pictureBox_Input->Image = this->pictureBox_Input->Image->FromHbitmap(bmpIn->GetHbitmap());
					// check for loaded image
					if (bmpIn)
					{
						startProcessing();
					}
					return;
				}
			}
		}
	}

	private: System::Void backgroundWorker_Webcam_RunWorkerCompleted(System::Object^  sender, System::ComponentModel::RunWorkerCompletedEventArgs^  e)
	{
		if (this->button_Webcam_StartStop->Text == "Stop")
		{
			this->backgroundWorker_Webcam->RunWorkerAsync();
		}
	}
	};
}