IP of Optics lidar and 360-cmos
proposed by Prof.Satoshi Nishimura image00 / Jichi Med Univ(JAPAN)

Specs: LIDar and 360-view cmos (paired).
Images combined in real time.

E-mail: If interested (snishi-tky(a-mark)ninus.ocn.ne.jp ) image00

Back to top image00



compared with intel-real sense
compared with intel-real sense


Movie: how it runs image00

Movie: how it runs image00

	
		using OpenCvSharp;
		using System;
		using System.Drawing;
		using System.Windows.Forms;
		using System.Text;
		using FTD2XX_NET;
		using System.Drawing.Imaging;
		using System.Drawing.Drawing2D;
		using System.Runtime.InteropServices;
		using System.Threading.Tasks;
		
		
		
		namespace WindowsFormsApp2
		{
		
			public partial class Form1 : Form
			{
				public int offsetangle = 12000;
		
				public int captflag = 0;
				public int resetflag = 0;
				public int motorflag = 0;
				public int relayon = 0;
				const int wid = 480;
				public int serialON = 0;
				public int prevtime = 0;
				public int camprevtime = 0;
		
				/// for image analysis
				public byte[] srcData1 = new byte[3 * 640 * wid];
				public byte[] srcData2 = new byte[3 * 640 * wid];
				public byte[] srcData3 = new byte[3 * 1200 * 1200];
		
				public int[,] disdata = new int[1000, 1000];
				public int[] discount = new int[1000];
				public int[,] predisdata = new int[10, 1000];
		
				public int[,] moveX = new int[3200, 2400];
				public int[,] moveY = new int[3200, 2400];
				public int[,] ougiX = new int[1200, 1200];
				public int[,] ougiY = new int[1200, 1200];
				public int[,] ougitype = new int[1200, 1200];
		
				Bitmap canvasRIGHT = new Bitmap(640, wid);
				Bitmap canvasLEFT = new Bitmap(640, wid);
				Bitmap canvasCENTER = new Bitmap(1200, 900);
				Bitmap canvasDOWN = new Bitmap(1200, 1200);
		
		
				Bitmap bitmap3 = new Bitmap(1200, 1200);
		
				Graphics Graphics3;
				Graphics Graphics4;
		
				/// for VIdeo capturing
				public int videoON = 0;
				public int videoON2 = 0;
				VideoCapture VideoCapture1;
				Mat Mat1;
				VideoCapture VideoCapture2;
				Mat Mat2;
		
				///  for RELAY BOARD
				public FTDI ftdi = new FTDI();
				public uint receivedBytes;
				private byte[] sentBytes = new byte[2];
		
				public Form1()
				{
					InitializeComponent();
				}
		
				private void Form1_Load(object sender, EventArgs e)
				{
		
					// Graphics1.DrawImage(bitmap1, 0, 0, Mat1.Cols, Mat1.Rows);
		
					// for lidar mapping
					Graphics3 = Graphics.FromImage(canvasCENTER);
					Graphics3.Clear(Color.LightGray);
					pictureBox3.Image = canvasCENTER;
		
					Graphics4 = Graphics.FromImage(canvasDOWN);
					pictureBox10.Image = canvasDOWN;
		
					// make zero time
					DateTime dt4 = DateTime.Now;
					prevtime = ((dt4.Hour * 60 + dt4.Minute) * 60 + dt4.Second) * 1000 + dt4.Millisecond;
					camprevtime = prevtime;
		
					// INIT data
					// resetimage array
					for (int pixelX = 0; pixelX < 640; pixelX++)
					{
						for (int pixelY = 0; pixelY < wid; pixelY++)
						{
							int indexR, indexG, indexB;
							indexR = (pixelX + pixelY * 640) * 3 + 2; //r
							indexG = (pixelX + pixelY * 640) * 3 + 1; //g
							indexB = (pixelX + pixelY * 640) * 3 + 0; //b
							srcData1[indexR] = 0;
							srcData1[indexG] = 0;
							srcData1[indexB] = 0;
							srcData2[indexR] = 0;
							srcData2[indexG] = 0;
							srcData2[indexB] = 0;
						}
					}
		
					for (int pixelX = 0; pixelX < 1200; pixelX++)
					{
						for (int pixelY = 0; pixelY < 1200; pixelY++)
						{
							int indexR, indexG, indexB;
							indexR = (pixelX + pixelY * 1200) * 3 + 2; //r
							indexG = (pixelX + pixelY * 1200) * 3 + 1; //g
							indexB = (pixelX + pixelY * 1200) * 3 + 0; //b
							srcData3[indexR] = 0;
							srcData3[indexG] = 0;
							srcData3[indexB] = 0;
						}
					}
		
					// reset distance array
					for (int k = 0; k < 1000; k++)
					{
						discount[k] = 0;
						for (int l = 0; l < 10; l++)
						{
							predisdata[l, k] = 0;
						}
					}
		
					// reset trans array, lens adujust
					for (int kx = 0; kx < 3200; kx++)
					{
						for (int ky = 0; ky < 2400; ky++)
						{
							moveX[kx, ky] = -1;
							moveY[kx, ky] = -1;
						}
					}
					////////////////////////////////////
					distortion(0.4);
					// reset ougi map
					for (int kx = 0; kx < 1200; kx++)
					{
						for (int ky = 0; ky < 1200; ky++)
						{
							ougitype[kx, ky] = -1;
							ougiX[kx, ky] = -1;
							ougiY[kx, ky] = -1;
						}
					}
					////////////////make ougi ////////////////////////////
					int picx, picy;
					int compx = 400, compy = 400, angle1 = 240, ratio3 = 3 ;
					for (int xx = compx; xx < 3200-compx; xx++)
					{
						for (int yy = compy; yy < 2400-compy; yy++)
						{
							double angle = (180-(double)xx / 3200 *angle1) * Math.PI / 180.0;
							double radius = (double)((6200 - ratio3 * yy) * 0.1);
							picx = (int)(Math.Cos(angle) * radius + 600);
							picy = 1200-(int)(Math.Sin(angle) * radius + 600);
							/// maximum 1000
							ougitype[picx, picy] = 1;
							ougiX[picx, picy] =moveX[xx,yy];
							ougiY[picx, picy] =moveY[xx,yy];
						}
					}
					for (int xx = compx; xx < 3200-compx; xx++)
					{
						for (int yy = compy; yy < 2400-compy; yy++)
						{
							double angle = (360 - (double)xx / 3200 * angle1) * Math.PI / 180.0;
							double radius = (double)((6200 - ratio3 * yy) * 0.1);
							picx = (int)(Math.Cos(angle) * radius + 600);
							picy = 1200 - (int)(Math.Sin(angle) * radius + 600);
							/// maximum 1000
							ougitype[picx, picy] = 2;
							ougiX[picx, picy] = moveX[xx, yy];
							ougiY[picx, picy] = moveY[xx, yy];
						}
					}
		
					// camera number
					numericUpDown1.Value = 0;
					numericUpDown1.Minimum = 0;
					numericUpDown1.Maximum = 5;
					numericUpDown1.TextAlign = HorizontalAlignment.Right;
					numericUpDown1.Increment = 1;
		
					//  serial communication port 
					numericUpDown8.Value = 10;
					numericUpDown8.Minimum = 8;
					numericUpDown8.Maximum = 12;
					numericUpDown8.TextAlign = HorizontalAlignment.Right;
					numericUpDown8.Increment = 1;
				}
		
				private void button1_Click(object sender, EventArgs e)
				{
					////////////////// OPEN CAMERA ////////////////////////
					if (numericUpDown1.Value == 0) { VideoCapture1 = new VideoCapture(0); }
					if (numericUpDown1.Value == 1) { VideoCapture1 = new VideoCapture(1); }
					if (numericUpDown1.Value == 2) { VideoCapture1 = new VideoCapture(2); }
					if (numericUpDown1.Value == 3) { VideoCapture1 = new VideoCapture(3); }
					if (numericUpDown1.Value == 4) { VideoCapture1 = new VideoCapture(4); }
					if (numericUpDown1.Value == 5) { VideoCapture1 = new VideoCapture(5); }
					if (!VideoCapture1.IsOpened())
					{
						MessageBox.Show("camera not found");
						videoON = 0;
					}
					else
					{
					  //  Graphics1 = pictureBox3.CreateGraphics();
						videoON++;
					  //  using (Mat1 = new Mat(0, 0, MatType.CV_8UC3))
						//{
					   //     VideoCapture1.Read(Mat1);
					   //    using (Bitmap bitmap1 = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(Mat1))
					   //     {
					   //         label1.Text = Mat1.Cols.ToString();
					   //         label10.Text = Mat1.Rows.ToString();
							   button1.Text = "connected";
								timer1.Enabled = true;
								timer1.Interval = 20;
						//    }
						//}
					}
				}
				private void button3_Click(object sender, EventArgs e)
				{
					////////////////  OPEN CAMERA 2
					if (numericUpDown1.Value == 0) { VideoCapture2 = new VideoCapture(0); }
					if (numericUpDown1.Value == 1) { VideoCapture2 = new VideoCapture(1); }
					if (numericUpDown1.Value == 2) { VideoCapture2 = new VideoCapture(2); }
					if (numericUpDown1.Value == 3) { VideoCapture2 = new VideoCapture(3); }
					if (numericUpDown1.Value == 4) { VideoCapture2 = new VideoCapture(4); }
					if (numericUpDown1.Value == 5) { VideoCapture2 = new VideoCapture(5); }
					if (!VideoCapture2.IsOpened())
					{
						MessageBox.Show("camera2 not found");
						videoON2 = 0;
					}
				  //  else
					{
					  //  Graphics2 = pictureBox6.CreateGraphics();
						videoON2++;
						button3.Text = "connected";
					 //   using (Mat2 = new Mat(0, 0, MatType.CV_8UC3))
					 //   {
					 //       VideoCapture2.Read(Mat2);
					 //       using (Bitmap bitmap2 = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(Mat2))
					 //       {
					 //       }
					 //   }
						timer1.Enabled = true;
						timer1.Interval = 20;
				   }
				}
				private void Form1_FormClosing(object sender, FormClosingEventArgs e)
				{
					//////////////////  CLOSE //////////////////////////
					if (videoON != 0)
					{
						VideoCapture1.Dispose();
			  //         Graphics1.Dispose();
					}
					if (videoON2 != 0)
					{
						VideoCapture2.Dispose();
			   //         Graphics2.Dispose();
					}
					if (serialON > 0)
					{
						serialPort1.Close();
					}
					if (relayon > 0)
					{
						sentBytes[0] = 0x00;
						ftdi.Write(sentBytes, 1, ref receivedBytes);
		
						DateTime dt2 = DateTime.Now;
						int starttime = ((dt2.Hour * 60 + dt2.Minute) * 60 + dt2.Second) * 1000 + dt2.Millisecond;
		
						for (int counti = 0; counti < 50;)
						{
							DateTime dt3 = DateTime.Now;
							int nowtime = ((dt3.Hour * 60 + dt3.Minute) * 60 + dt3.Second) * 1000 + dt3.Millisecond;
		
							if ((nowtime - starttime) > 250)
							{
								counti = counti + 5000;
							}
						}
						ftdi.Close();
					}
				}
		
				private void timer1_Tick(object sender, EventArgs e)
				{
					DateTime dt5 = DateTime.Now;
					int now2time = ((dt5.Hour * 60 + dt5.Minute) * 60 + dt5.Second) * 1000 + dt5.Millisecond;
					int elltime = now2time - camprevtime;
					camprevtime = now2time;
					label15.Text = elltime.ToString("D4") + "msec";
		
					timer1.Enabled = false;
					///// BMP SAVE
					if (videoON != 0 && videoON2 != 0)
					{
						using (Mat1 = new Mat(0, 0, MatType.CV_8UC3))
						{
							using (Mat2 = new Mat(0, 0, MatType.CV_8UC3))
							{
							   
								VideoCapture2.Read(Mat2);
								VideoCapture1.Read(Mat1);
								using (Bitmap bitmap1 = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(Mat1))
									{
										using (Bitmap bitmap2 = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(Mat2))
										{
		
											// EXCLUSIVE use image data for "bmpdata"//
											System.Drawing.Imaging.BitmapData bmpData1 = bitmap1.LockBits(new Rectangle(0, 0, bitmap1.Width, bitmap1.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap1.PixelFormat);
											System.Runtime.InteropServices.Marshal.Copy(bmpData1.Scan0, srcData1, 0, srcData1.Length);
											System.Drawing.Imaging.BitmapData bmpData2 = bitmap2.LockBits(new Rectangle(0, 0, bitmap2.Width, bitmap2.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap2.PixelFormat);
											System.Runtime.InteropServices.Marshal.Copy(bmpData2.Scan0, srcData2, 0, srcData2.Length);
											System.Drawing.Imaging.BitmapData bmpData3 = bitmap3.LockBits(new Rectangle(0, 0, bitmap3.Width, bitmap3.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap2.PixelFormat);
											System.Runtime.InteropServices.Marshal.Copy(bmpData3.Scan0, srcData3, 0, srcData3.Length);
		
										for (int pixelX = 0; pixelX < 1200; pixelX++)
										{
											for (int pixelY = 0; pixelY < 1200; pixelY++)
											{
												int indexR, indexG, indexB;
												indexR = (pixelX + pixelY * 1200) * 3 + 2; //r
												indexG = (pixelX + pixelY * 1200) * 3 + 1; //g
												indexB = (pixelX + pixelY * 1200) * 3 + 0; //b
		
		
												srcData3[indexR] = 20;
												srcData3[indexG] = 20;
												srcData3[indexB] = 20;
		
												if (ougitype[pixelX, pixelY] == 1)
												{
													if (ougiX[pixelX, pixelY] > 0 && ougiY[pixelX, pixelY] > 0)
													{
														int xr, xg, xb;
														xr = (ougiX[pixelX, pixelY] + ougiY[pixelX, pixelY] * 640) * 3 + 2; //r
														xg = (ougiX[pixelX, pixelY] + ougiY[pixelX, pixelY] * 640) * 3 + 1; //g
														xb = (ougiX[pixelX, pixelY] + ougiY[pixelX, pixelY] * 640) * 3 + 0; //b
		
														int rpix = srcData1[xr] - 50;
														int gpix = srcData1[xg] - 50;
														int bpix = srcData1[xb] - 50;
														if (rpix < 0) { rpix = 0; }
														if (gpix < 0) { gpix = 0; }
														if (bpix < 0) { bpix = 0; }
														srcData3[indexR] = (byte)rpix;
														srcData3[indexG] = (byte)gpix;
														srcData3[indexB] = (byte)bpix;
		
													}
												}
												else if (ougitype[pixelX, pixelY] == 2)
												{
													if (ougiX[pixelX, pixelY] > 0 && ougiY[pixelX, pixelY] > 0)
													{
														int xr, xg, xb;
														xr = (ougiX[pixelX, pixelY] + ougiY[pixelX, pixelY] * 640) * 3 + 2; //r
														xg = (ougiX[pixelX, pixelY] + ougiY[pixelX, pixelY] * 640) * 3 + 1; //g
														xb = (ougiX[pixelX, pixelY] + ougiY[pixelX, pixelY] * 640) * 3 + 0; //b
														int rpix = srcData2[xr] - 50;
														int gpix = srcData2[xg] - 50;
														int bpix = srcData2[xb] - 50;
														if (rpix < 0) { rpix = 0; }
														if (gpix < 0) { gpix = 0; }
														if (bpix < 0) { bpix = 0; }
														srcData3[indexR] = (byte)rpix;
														srcData3[indexG] = (byte)gpix;
														srcData3[indexB] = (byte)bpix;
													}
												}
												else
												{
		
												}
		
											}
										}
		
												// UNLOCK BITS
												System.Runtime.InteropServices.Marshal.Copy(srcData3, 0, bmpData3.Scan0, srcData3.Length);
												System.Runtime.InteropServices.Marshal.Copy(srcData2, 0, bmpData2.Scan0, srcData2.Length);
												System.Runtime.InteropServices.Marshal.Copy(srcData1, 0, bmpData1.Scan0, srcData1.Length);
												bitmap1.UnlockBits(bmpData1);
												bitmap2.UnlockBits(bmpData2);
												bitmap3.UnlockBits(bmpData3);
												//  Graphics1.DrawImage(bitmap1, 0, 0, Mat1.Cols, Mat1.Rows);
												//  Graphics2.DrawImage(bitmap2, 0, 0, Mat2.Cols, Mat2.Rows);
												Graphics4.DrawImage(bitmap3, -100, -100, 1200, 1200);
		
												if (captflag > 0)
												{
		
													for (int o = 10; o < 549; o++)
													{
														int disabi = 0, nexabi = 0;
														if ((predisdata[1, o] - predisdata[0, o]) * (predisdata[1, o] - predisdata[0, o]) < 100)
														{
															disabi = predisdata[0, o];
														}
														else if ((predisdata[2, o] - predisdata[1, o]) * (predisdata[2, o] - predisdata[1, o]) < 100)
														{
															disabi = predisdata[1, o];
														}
														else
														{
															disabi = predisdata[2, o];
														}
		
														if ((predisdata[1, o + 1] - predisdata[0, o + 1]) * (predisdata[1, o + 1] - predisdata[0, o + 1]) < 100)
														{
															nexabi = predisdata[0, o + 1];
														}
														else if ((predisdata[2, o + 1] - predisdata[1, o + 1]) * (predisdata[2, o + 1] - predisdata[1, o + 1]) < 100)
														{
															nexabi = predisdata[1, o + 1];
														}
														else
														{
															nexabi = predisdata[2, o + 1];
														}
														int pix1, pix2, piy1, piy2;
														pix1 = (int)(Math.Cos((double)o / 72) * (double)disabi / 2) * 2;
														piy1 = (int)(Math.Sin((double)o / 72) * (double)disabi / 2) * 2;
														pix2 = (int)(Math.Cos((double)(o + 1) / 72) * (double)nexabi / 2) * 2;
														piy2 = (int)(Math.Sin((double)(o + 1) / 72) * (double)nexabi / 2) * 2;
														if (disabi != 0 && nexabi != 0 && (disabi - nexabi) * (disabi - nexabi) < 1000)
														{
															Graphics4.DrawLine(Pens.Blue, pix1 + 500, piy1 + 500, pix2 + 500, piy2 + 500);
		
														}
														else
														{
															Graphics4.DrawLine(Pens.Green, pix1 + 500, piy1 + 500, pix2 + 500, piy2 + 500);
		
														}
														Graphics4.DrawRectangle(Pens.Blue, pix1 + 501, piy1 + 501, 2, 2);
														Graphics4.DrawRectangle(Pens.Blue, pix1 + 502, piy1 + 502, 4, 4);
		
													}
		
													Graphics4.DrawEllipse(Pens.Gray, 400, 400, 200, 200);
													Graphics4.DrawEllipse(Pens.Gray, 450, 450, 100, 100);
													Graphics4.DrawEllipse(Pens.Gray, 300, 300, 400, 400);
													Graphics4.DrawEllipse(Pens.Gray, 200, 200, 600, 600);
												}
												pictureBox10.Image = canvasDOWN;
		
		
		
											}
										}
										
									}
								
							
						}
					}
				 
					timer1.Enabled = true;
				}
			 
		
				private void button2_Click_1(object sender, EventArgs e)
				{
					///////////////// OPEN SERIAL PORT
					try
					{
						if (numericUpDown8.Value == 8)
						{
							serialPort1.PortName = "COM8";
						}
						else if (numericUpDown8.Value == 9)
						{
							serialPort1.PortName = "COM9";
						}
						else if (numericUpDown8.Value == 10)
						{
							serialPort1.PortName = "COM10";
						}
						else if (numericUpDown8.Value == 11)
						{
							serialPort1.PortName = "COM11";
						}
						else
						{
							serialPort1.PortName = "COM20";
						}
						serialPort1.BaudRate = 128000;
						serialPort1.Parity = System.IO.Ports.Parity.None;
						serialPort1.DataBits = 8;
						serialPort1.StopBits = System.IO.Ports.StopBits.One;
						serialPort1.Open();
		
						button2.Text = serialPort1.PortName + "open";
						serialON++;
					}
					catch (Exception ex)
					{
						MessageBox.Show(ex.Message, "error to serial open", MessageBoxButtons.OK, MessageBoxIcon.Stop);
					}
				}
		
				private void button4_Click_1(object sender, EventArgs e)
				{
					// A560 SCAN command
					timer2.Enabled = false;
					serialPort1.RtsEnable = false;
					byte[] edata = new byte[2];
					edata[0] = 0xA5;
					edata[1] = 0x60;
		
					byte[] readdata = new byte[12];
					for (int i = 0; i < 12; i++)
					{
						readdata[i] = 0xFF;
					}
		
					serialPort1.Write(edata, 0, edata.Length);
		
					DateTime dt2 = DateTime.Now;
					int starttime = ((dt2.Hour * 60 + dt2.Minute) * 60 + dt2.Second) * 1000 + dt2.Millisecond;
		
					for (int counti = 0; counti < 100;)
					{
						if (serialPort1.BytesToRead > 0)
						{
							DateTime dt3 = DateTime.Now;
							int nowtime = ((dt3.Hour * 60 + dt3.Minute) * 60 + dt3.Second) * 1000 + dt3.Millisecond;
							int dcheck;
							serialPort1.Read(readdata, 0, 1);
							dcheck = readdata[0];
							if ((nowtime - starttime) > 250)
							{
								counti = counti + 5000;
							}
							if (dcheck == 0xA5)
							{
								counti = counti + 2000;
							}
							label4.Text = readdata[0].ToString("x2");
						}
					}
					if (serialPort1.BytesToRead > 12)
					{
						serialPort1.Read(readdata, 0, 12);
					}
					label4.Text = readdata[0].ToString("x2");
					label5.Text = readdata[1].ToString("x2");
					label6.Text = readdata[2].ToString("x2");
					label7.Text = readdata[3].ToString("x2");
					label23.Text = readdata[4].ToString("x2");
					label24.Text = readdata[5].ToString("x2");
					label25.Text = readdata[6].ToString("x2");
					label26.Text = readdata[7].ToString("x2");
					label33.Text = readdata[8].ToString("x2");
					label34.Text = readdata[9].ToString("x2");
					label35.Text = readdata[10].ToString("x2");
					label36.Text = readdata[11].ToString("x2");
		
					serialPort1.RtsEnable = true;
					timer2.Enabled = true;
				}
		
				private void button5_Click_1(object sender, EventArgs e)
				{
					// A565 stop
					timer2.Enabled = false;
					serialPort1.RtsEnable = false;
		
					byte[] edata = new byte[2];
					edata[0] = 0xA5;
					edata[1] = 0x65;
		
					serialPort1.Write(edata, 0, edata.Length);
		
					serialPort1.RtsEnable = true;
					timer2.Enabled = true;
				}
		
				private void button6_Click_1(object sender, EventArgs e)
				{
					// A590 device info command
					serialPort1.RtsEnable = false;
					timer2.Enabled = false;
		
					byte[] edata = new byte[2];
					edata[0] = 0xA5;
					edata[1] = 0x90;
		
					byte[] readdata = new byte[12];
					for (int i = 0; i < 12; i++)
					{
						readdata[i] = 0xFF;
					}
		
					serialPort1.Write(edata, 0, edata.Length);
		
					DateTime dt2 = DateTime.Now;
					int starttime = ((dt2.Hour * 60 + dt2.Minute) * 60 + dt2.Second) * 1000 + dt2.Millisecond;
		
					for (int counti = 0; counti < 100;)
					{
						if (serialPort1.BytesToRead > 0)
						{
							DateTime dt3 = DateTime.Now;
							int nowtime = ((dt3.Hour * 60 + dt3.Minute) * 60 + dt3.Second) * 1000 + dt3.Millisecond;
							int dcheck;
							serialPort1.Read(readdata, 0, 1);
							dcheck = readdata[0];
							if ((nowtime - starttime) > 250)
							{
								counti = counti + 5000;
							}
							if (dcheck == 0xA5)
							{
								counti = counti + 2000;
							}
							label4.Text = readdata[0].ToString("x2");
						}
					}
		
					if (serialPort1.BytesToRead > 12)
					{
						serialPort1.Read(readdata, 0, 12);
					}
					label4.Text = readdata[0].ToString("x2");
					label5.Text = readdata[1].ToString("x2");
					label6.Text = readdata[2].ToString("x2");
					label7.Text = readdata[3].ToString("x2");
					label23.Text = readdata[4].ToString("x2");
					label24.Text = readdata[5].ToString("x2");
					label25.Text = readdata[6].ToString("x2");
					label26.Text = readdata[7].ToString("x2");
					label33.Text = readdata[8].ToString("x2");
					label34.Text = readdata[9].ToString("x2");
					label35.Text = readdata[10].ToString("x2");
					label36.Text = readdata[11].ToString("x2");
		
					serialPort1.RtsEnable = true;
					timer2.Enabled = true;
				}
		
				private void button7_Click_1(object sender, EventArgs e)
				{
		
					timer1.Enabled = false;
					
						///// BMP SAVE
						///
						if (videoON != 0 && videoON2 != 0)
						{
		
						Random r1 = new System.Random();
						int filenum = r1.Next(0, 100);
		
						bitmap3.Save(
							@"D:\HDMIcapture2\backup.jpg",
						System.Drawing.Imaging.ImageFormat.Jpeg
							);
					}
					
					timer1.Enabled = true;
				}
		
		
				private void button8_Click_1(object sender, EventArgs e)
				{
		
					//a591 health status
					serialPort1.RtsEnable = false;
					timer2.Enabled = false;
		
					byte[] edata = new byte[2];
					edata[0] = 0xA5;
					edata[1] = 0x91;
		
					byte[] readdata = new byte[12];
					for (int i = 0; i < 12; i++)
					{
						readdata[i] = 0xFF;
					}
		
					serialPort1.Write(edata, 0, edata.Length);
		
					DateTime dt2 = DateTime.Now;
					int starttime = ((dt2.Hour * 60 + dt2.Minute) * 60 + dt2.Second) * 1000 + dt2.Millisecond;
		
					for (int counti = 0; counti < 100;)
					{
						if (serialPort1.BytesToRead > 0)
						{
							DateTime dt3 = DateTime.Now;
							int nowtime = ((dt3.Hour * 60 + dt3.Minute) * 60 + dt3.Second) * 1000 + dt3.Millisecond;
							int dcheck;
							serialPort1.Read(readdata, 0, 1);
							dcheck = readdata[0];
							if ((nowtime - starttime) > 250)
							{
								counti = counti + 5000;
							}
							if (dcheck == 0xA5)
							{
								counti = counti + 2000;
							}
							label4.Text = readdata[0].ToString("x2");
						}
					}
		
					if (serialPort1.BytesToRead > 12)
					{
						serialPort1.Read(readdata, 0, 12);
					}
					label4.Text = readdata[0].ToString("x2");
					label5.Text = readdata[1].ToString("x2");
					label6.Text = readdata[2].ToString("x2");
					label7.Text = readdata[3].ToString("x2");
					label23.Text = readdata[4].ToString("x2");
					label24.Text = readdata[5].ToString("x2");
					label25.Text = readdata[6].ToString("x2");
					label26.Text = readdata[7].ToString("x2");
					label33.Text = readdata[8].ToString("x2");
					label34.Text = readdata[9].ToString("x2");
					label35.Text = readdata[10].ToString("x2");
					label36.Text = readdata[11].ToString("x2");
		
					serialPort1.RtsEnable = true;
					timer2.Enabled = true;
				}
		
		
		
		
		
		
				private void numericUpDown1_ValueChanged(object sender, EventArgs e)
				{
		
				}
				private void pictureBox3_Click(object sender, EventArgs e)
				{
		
				}
		
		
				private void waitsecone()
				{
		
					timer1.Stop();
					timer1.Enabled = false;
					if (videoON != 0)                 ////////////////////HDMI CAM ON??? ////////////////////
					{
						using (Mat1 = new Mat(0, 0, MatType.CV_8UC3))               // for HDMI CAPTURE
						{
		
							int counti = 0;
							int nowsec = 0;
							int waittime = 5;
							DateTime dt = DateTime.Now;
							nowsec = dt.Second;
							waittime = nowsec + 1;
							if (nowsec == 59)
							{
								waittime = 0;
		
							}
							for (counti = 0; counti < 1;)
							{
								VideoCapture1.Read(Mat1);
								using (Bitmap bitmap1 = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(Mat1))
								{
								 
								}
								DateTime dt2 = DateTime.Now;
								nowsec = dt2.Second;
								if (nowsec == waittime)
								{
									counti++;
								}
							}
						}
					}
					timer1.Start();
					timer1.Enabled = true;
				}
		
		
				private void button10_Click_1(object sender, EventArgs e)
				{
					//a580 soft restart
					timer2.Enabled = false;
		
					byte[] edata = new byte[2];
					edata[0] = 0xA5;
					edata[1] = 0x80;
		
					byte[] readdata = new byte[12];
					for (int i = 0; i < 12; i++)
					{
						readdata[i] = 0xFF;
					}
		
					serialPort1.Write(edata, 0, edata.Length);
		
					DateTime dt2 = DateTime.Now;
					int starttime = ((dt2.Hour * 60 + dt2.Minute) * 60 + dt2.Second) * 1000 + dt2.Millisecond;
		
		
					for (int counti = 0; counti < 100;)
					{
						DateTime dt3 = DateTime.Now;
						int nowtime = ((dt3.Hour * 60 + dt3.Minute) * 60 + dt3.Second) * 1000 + dt3.Millisecond;
						if ((nowtime - starttime) > 250)
						{
							counti = counti + 5000;
						}
		
						if (serialPort1.BytesToRead > 0)
						{
							string indata = serialPort1.ReadExisting();
							label16.Text = indata;
						}
					}
					timer2.Enabled = true;
				}
		
				private void button11_Click_1(object sender, EventArgs e)
				{
					//continuous capturing start
					if (captflag == 0)
					{
						captflag = 1;
						button11.BackColor = Color.Red;
						timer2.Enabled = true;
						timer2.Interval = 100;
						timer2.Start();
						serialPort1.RtsEnable = true;
		
						if (motorflag == 1)
						{
							sentBytes[0] = 0xFF;
							ftdi.Write(sentBytes, 1, ref receivedBytes);
							motorflag = 2;
						}
		
						if (serialPort1.BytesToRead > 12)
						{
							byte[] readdata = new byte[12];
							for (int i = 0; i < 12; i++)
							{
								readdata[i] = 0xFF;
							}
							serialPort1.Read(readdata, 0, 12);
							label4.Text = readdata[0].ToString("x2");
							label5.Text = readdata[1].ToString("x2");
							label6.Text = readdata[2].ToString("x2");
							label7.Text = readdata[3].ToString("x2");
							label23.Text = readdata[4].ToString("x2");
							label24.Text = readdata[5].ToString("x2");
							label25.Text = readdata[6].ToString("x2");
							label26.Text = readdata[7].ToString("x2");
							label33.Text = readdata[8].ToString("x2");
							label34.Text = readdata[9].ToString("x2");
							label35.Text = readdata[10].ToString("x2");
							label36.Text = readdata[11].ToString("x2");
						}
		
					}
					else
					{
						captflag = 0;
						button11.BackColor = Color.LightGray;
						timer2.Enabled = false;
						timer2.Stop();
						serialPort1.RtsEnable = false;
					}
				}
		
				public void timer2task()
				{
					
						  if (captflag > 0)
						  {
							  byte[] edata = new byte[2];
							  edata[0] = 0xA5;
							  edata[1] = 0x60;
		
							  DateTime dt1 = DateTime.Now;
							  if (resetflag > 1)
							  {
								  edata[0] = 0xA5;
								  edata[1] = 0x80;
								  serialPort1.Write(edata, 0, edata.Length);
								  resetflag = 0;
							  }
		
							// dis array
							for (int k = 0; k < 1000; k++)
							  {
								  discount[k] = 0;
							  }
		
							  for (int countj = 0; countj < 3; countj++)
							  {
								  serialPort1.Write(edata, 0, edata.Length);
							  }
		
							  DateTime dt2 = DateTime.Now;
							  int starttime = ((dt2.Hour * 60 + dt2.Minute) * 60 + dt2.Second) * 1000 + dt2.Millisecond;
							  int prev = 0;
							  int jmax = 0;
		
							  for (int counti = 0; counti < 15;)
							  {
								  DateTime dt3 = DateTime.Now;
								  int nowtime = ((dt3.Hour * 60 + dt3.Minute) * 60 + dt3.Second) * 1000 + dt3.Millisecond;
								  if ((nowtime - starttime) > 30)
								  {
									  counti = counti + 5000;
								  }
		
								  if (serialPort1.BytesToRead > 40)
								  {
									  counti = counti + 5000;
									  string indata = serialPort1.ReadExisting();
									  byte[] bytes = Encoding.Default.GetBytes(indata);
									  counti = counti + 500;
									  int jlong = bytes.Length;
		
									  label13.Text = jlong.ToString("D6") + " buffe";
		
									  if (jmax < jlong)
									  {
										  jmax = jlong;
									  }
		
									  int[] intdata = new int[jlong];
									  for (int i = 0; i < jlong; i++)
									  {
										  intdata[i] = (int)bytes[i];
									  }
		
									  int l = 0;
									  int m = 0;
									  int n = 0;
		
									  Graphics3.Clear(Color.LightGray);
		
									  for (int k = 0; k < jlong - 20; k++)
									  {
										  if (intdata[k] == 0x55)
										  {
											  int intv = (prev - k);
											  prev = k;
											  label2.Text = intv.ToString() + ":55to55";
											  n++;
		
											  int i = k;
											  label41.Text = intdata[i].ToString("X2") + "header";
											  label42.Text = intdata[i + 1].ToString("X2") + "sing00 mutl01";
											  label43.Text = intdata[i + 2].ToString("X2") + "num of multi";
											  label44.Text = intdata[i + 3].ToString("X2") + "start";
											  label45.Text = intdata[i + 4].ToString("X2") + "start";
											  label46.Text = intdata[i + 5].ToString("X2") + "end";
											  label47.Text = intdata[i + 6].ToString("X2") + "end";
											  label48.Text = intdata[i + 7].ToString("X2") + "check";
											  label49.Text = intdata[i + 8].ToString("X2") + "check2";
											  label50.Text = intdata[i + 9].ToString("X2") + "distance";
											  label51.Text = intdata[i + 10].ToString("X2") + "distne"; ;
		
											  int endangle, startangle, diffangle, samplenum;
											  double nowangle, nowdis;
		
											  endangle = intdata[i + 6] * 256 * 256 / 2 + intdata[i + 5];
											  startangle = intdata[i + 4] * 256 * 256 / 2 + intdata[i + 3];
											  samplenum = intdata[i + 2] - 1;
											  if (samplenum < 1)
											  {
												  samplenum = 1;
											  }
											  endangle = endangle / 128+offsetangle;
											  startangle = startangle / 128+offsetangle;
		
											  if (endangle > startangle)
											  {
												  diffangle = (endangle - startangle) / samplenum;
												  for (int countk = 0; countk < samplenum; countk++)
												  {
													  if ((i + 10 + countk * 2) < jlong)
													  {
														  nowdis = intdata[i + 10 + countk * 2] * 256 * 256 + intdata[i + 9 + countk * 2];
														  nowangle = startangle + countk * diffangle;
		
														  if (nowdis < 0.01)
														  {
		
														  }
														  else
														  {
															// nowangle = nowangle + Math.Atan(21.8 * (155.3 - nowdis) / (155.3 * nowdis));
		
															int nv2 = (int)numericUpDown2.Value;
															  if (nv2 < 2)
															  {
																  nowdis = Math.Pow((double)nowdis, (double)nv2 / 10);
																  nowdis = nowdis * 20;
															  }
															  else if (nv2 < 3)
															  {
																  nowdis = Math.Pow((double)nowdis, (double)nv2 / 10);
																  nowdis = nowdis * 5;
															  }
															  else if (nv2 < 4)
															  {
																  nowdis = Math.Pow((double)nowdis, (double)nv2 / 10);
																  nowdis = nowdis;
															  }
															  else if (nv2 < 5)
															  {
																  nowdis = Math.Pow((double)nowdis, (double)nv2 / 10);
																  nowdis = nowdis / 5;
															  }
															  else if (nv2 < 6)
															  {
																  nowdis = Math.Pow((double)nowdis, (double)nv2 / 10);
																  nowdis = nowdis / 10;
															  }
															  else if (nv2 < 7)
															  {
																  nowdis = Math.Pow((double)nowdis, (double)nv2 / 10);
																  nowdis = nowdis / 50;
															  }
		
															  else if (nv2 < 8)
															  {
																  nowdis = Math.Pow((double)nowdis, (double)nv2 / 10);
																  nowdis = nowdis / 120;
															  }
															  else if (nv2 < 9)
															  {
																  nowdis = Math.Pow((double)nowdis, (double)nv2 / 10);
																  nowdis = nowdis / 600;
															  }
															  else if (nv2 < 10)
															  {
																  nowdis = Math.Pow((double)nowdis, (double)nv2 / 10);
																  nowdis = nowdis / 2000;
															  }
															  else
															  {
																  nowdis = Math.Pow((double)nowdis, (double)nv2 / 10);
																  nowdis = nowdis / 10000;
															  }
														  }
		
														  nowangle = nowangle / 60;
														  label52.Text = nowangle.ToString("F2") + "angle";
														  label53.Text = nowdis.ToString("F2") + "distance";
														  label54.Text = samplenum.ToString() + "samplenum";
		
		
		
														  if (samplenum > 0 && diffangle < 300 && diffangle > 70)
														  {
		
															// Graphics3.DrawRectangle(Pens.Red, (int)nowangle, (int)nowdis, 2, 2);
		
															disdata[(int)nowangle, discount[(int)nowangle]] = (int)nowdis;
															  discount[(int)nowangle] = discount[(int)nowangle] + 1;
															  int pix, piy;
															  pix = (int)(Math.Cos(nowangle / 100) * nowdis / 2);
															  piy = (int)(Math.Sin(nowangle / 100) * nowdis / 2);
															//    Graphics3.DrawRectangle(Pens.Blue, pix + 200, piy + 200, 2, 2);
														}
													  }
													  else
													  {
														//  Graphics3.DrawRectangle(Pens.Red, 0, 0, 100, 100);
													}
												  }
											  }
											  else
											  {
												//      endangle = endangle + 0xFFFF / 128;
												//      diffangle = (endangle - startangle) / samplenum;
		
											}
										  }
									  }
		
									  pictureBox4.Image = canvasCENTER;
		
		
									  Graphics3.DrawRectangle(Pens.Blue, 190, 190, 20, 20);
		
									  for (int o = 0; o < 1000; o++)
									  {
										  int middata = 0;
										  if (discount[o] > 0)
										  {
											  int stacknum = discount[o];
											  int[] stackdata = new int[stacknum];
											  for (int mm = 0; mm < stacknum; mm++)
											  {
												  stackdata[mm] = disdata[o, mm];
											  }
											  Array.Sort(stackdata);
											  middata = stackdata[stacknum / 2];
											  Graphics3.DrawRectangle(Pens.Red, o, middata, 2, 2);
										  }
		
										  if (middata == 0 && o > 2)
										  {
											  if (predisdata[0, o - 1] != 0)
											  {
												  middata = predisdata[0, o - 1];
											  }
											  else if (predisdata[0, o - 2] != 0)
											  {
												  middata = predisdata[0, o - 2];
											  }
										  }
		
										  predisdata[9, o] = predisdata[8, o];
										  predisdata[8, o] = predisdata[7, o];
										  predisdata[7, o] = predisdata[6, o];
										  predisdata[6, o] = predisdata[5, o];
										  predisdata[5, o] = predisdata[4, o];
										  predisdata[4, o] = predisdata[3, o];
										  predisdata[3, o] = predisdata[2, o];
										  predisdata[2, o] = predisdata[1, o];
										  predisdata[1, o] = predisdata[0, o];
										  predisdata[0, o] = middata;
		
										  if ((predisdata[1, o] - predisdata[0, o]) * (predisdata[1, o] - predisdata[0, o]) < 100)
										  {
		
											//   Graphics3.DrawRectangle(Pens.Blue, pix + 200, piy + 200, 2, 2);
										}
		
									  }
		
									  for (int o = 10; o < 549; o++)
									  {
										  int disabi = 0, nexabi = 0;
										  if ((predisdata[1, o] - predisdata[0, o]) * (predisdata[1, o] - predisdata[0, o]) < 100)
										  {
											  disabi = predisdata[0, o];
										  }
										  else if ((predisdata[2, o] - predisdata[1, o]) * (predisdata[2, o] - predisdata[1, o]) < 100)
										  {
											  disabi = predisdata[1, o];
										  }
										  else
										  {
											  disabi = predisdata[2, o];
										  }
		
										  if ((predisdata[1, o + 1] - predisdata[0, o + 1]) * (predisdata[1, o + 1] - predisdata[0, o + 1]) < 100)
										  {
											  nexabi = predisdata[0, o + 1];
										  }
										  else if ((predisdata[2, o + 1] - predisdata[1, o + 1]) * (predisdata[2, o + 1] - predisdata[1, o + 1]) < 100)
										  {
											  nexabi = predisdata[1, o + 1];
										  }
										  else
										  {
											  nexabi = predisdata[2, o + 1];
										  }
										  int pix1, pix2, piy1, piy2;
										  pix1 = (int)(Math.Cos((double)o / 72) * (double)disabi / 2);
										  piy1 = (int)(Math.Sin((double)o / 72) * (double)disabi / 2);
										  pix2 = (int)(Math.Cos((double)(o + 1) / 72) * (double)nexabi / 2);
										  piy2 = (int)(Math.Sin((double)(o + 1) / 72) * (double)nexabi / 2);
										  if (disabi != 0 && nexabi != 0 && (disabi - nexabi) * (disabi - nexabi) < 1000)
										  {
											  Graphics3.DrawLine(Pens.Blue, pix1 + 200, piy1 + 200, pix2 + 200, piy2 + 200);
		
										  }
										  else
										  {
											  Graphics3.DrawLine(Pens.Gray, pix1 + 200, piy1 + 200, pix2 + 200, piy2 + 200);
		
										  }
										  Graphics3.DrawRectangle(Pens.Blue, pix1 + 200, piy1 + 200, 2, 2);
									  }
		
		
									  for (int k = 2; k < jlong - 1; k++)
									  {
										  if (intdata[k] == 0x01)
										  {
											  l++;
										  }
										  if (intdata[k] == 0x00)
										  {
											  m++;
										  }
									  }
									  label12.Text = l.ToString("D4") + " in 01";
									  label9.Text = m.ToString("D4") + " in 00";
									  label22.Text = n.ToString("D4") + " in 55";
								  }
							  }
							  if (jmax < 90 && false)
							  {
								  edata[0] = 0xA5;
								  edata[1] = 0x80;
		
								  serialPort1.Write(edata, 0, edata.Length);
								  dt2 = DateTime.Now;
								  starttime = ((dt2.Hour * 60 + dt2.Minute) * 60 + dt2.Second) * 1000 + dt2.Millisecond;
								  for (int counti = 0; counti < 100;)
								  {
									  DateTime dt3 = DateTime.Now;
									  int nowtime = ((dt3.Hour * 60 + dt3.Minute) * 60 + dt3.Second) * 1000 + dt3.Millisecond;
									  if ((nowtime - starttime) > 250)
									  {
										  counti = counti + 5000;
									  }
		
									  if (serialPort1.BytesToRead > 0)
									  {
										  string indata = serialPort1.ReadExisting();
										  label16.Text = indata;
									  }
								  }
							  }
						  }
					  
				}
				private void timer2_Tick(object sender, EventArgs e)
				{
					// check serial transport
					// make distance from LIDAR
		
					timer2.Enabled = false;
					timer2.Stop();
		
					timer2task();
		
		
					timer2.Enabled = true;
					timer2.Start();
				}
		
				private void button9_Click_1(object sender, EventArgs e)
				{
					FTDI.FT_STATUS ftStatus = FTDI.FT_STATUS.FT_OK;
					ftdi = new FTDI();
					ftStatus = ftdi.OpenByIndex((byte)(numericUpDown3.Value));
					if (ftStatus != FTDI.FT_STATUS.FT_OK)
					{
						button9.Text = "NO DEVICE";
						return;
					}
					//Reset device
					ftStatus = ftdi.ResetDevice();
					if (ftStatus != FTDI.FT_STATUS.FT_OK)
					{
						button9.Text = "NO DEVICE";
						return;
					}
					//Set Baud Rate
					ftStatus = ftdi.SetBaudRate(115200);
					if (ftStatus != FTDI.FT_STATUS.FT_OK)
					{
						button9.Text = "NO DEVICE";
						return;
					}
					//Set Bit Bang
					ftStatus = ftdi.SetBitMode(255, FTD2XX_NET.FTDI.FT_BIT_MODES.FT_BIT_MODE_SYNC_BITBANG);
					if (ftStatus != FTDI.FT_STATUS.FT_OK)
					{
						button9.Text = "NO DEVICE";
						return;
					}
					if (ftStatus != FTDI.FT_STATUS.FT_OK)
					{
						button9.Text = "NO DEVICE";
						return;
					}
					else
					{
						relayon++;
						string portName;
						ftdi.GetCOMPort(out portName);
						button9.Text = portName;
						motorflag = 1;
						sentBytes[0] = 0x00;
						ftdi.Write(sentBytes, 1, ref receivedBytes);
		
					}
				}
		
				private void button12_Click_1(object sender, EventArgs e)
				{
					// motor relay off
					if (relayon > 0)
					{
						sentBytes[0] = 0x00;
						ftdi.Write(sentBytes, 1, ref receivedBytes);
		
						motorflag = 1;
					}
				}
				private void button13_Click_1(object sender, EventArgs e)
				{
					// motorrelay ON
					if (relayon > 0)
					{
						sentBytes[0] = 0xFF;
						ftdi.Write(sentBytes, 1, ref receivedBytes);
		
						motorflag = 2;
					}
				}
		
				public void distortion(double factor)
				{
					int siHeight = 2400, siWidth = 3200;  //??????????????????????
		
					//Calcula a amplitude máxima possível para a imagem e multiplica pelo fator desejados
					double amp = 0;
					double ang = Math.PI * 0.5;
					for (Int32 a = 0; a < siHeight; a++)
					{
						int y = (int)((siHeight / 2) - amp * Math.Sin(ang));
						if ((y < 0) || (y > siHeight))
							break;
						amp = a;
					}
					amp = (amp - 2) * (factor < -1 ? -1 : (factor > 1 ? 1 : factor));
		
				   
					int index = ((1 * siWidth) + 1) * 3;
					do
					{
		
						Int32 y = (Int32)((index / 3) / siWidth);
						Int32 x = (index / 3) - (y * siWidth);
						Int32 x1, y1;
						x1 = siWidth;
						y1 = siHeight;
						System.Drawing.Point pt = NewPoint(new System.Drawing.Point(x, y), 3200,2400, amp, factor < 0);
		
									 //Indice de bytes onde será aplicada o pixel
						Int32 dstIndex = ((pt.Y * siWidth) + pt.X) *3;
		
						moveX[pt.X, pt.Y] = (int)(x/5);
						moveY[pt.X, pt.Y] = (int)(y/5);
		
						index = index + 3;
						
					} while (index < (3200*2400*3));
		
				   
				} 
		
		
				static public Bitmap BarrelDistortion(Bitmap sourceImage, double factor, Boolean autoCrop, Color backgroundColor,float percent)
				{
					Bitmap StartImage = null;
					BitmapData srcBitmapData = null;
					Byte[] srcPixels = null;
					Byte[] dstPixels = null;
					Bitmap NewImage = null;
					BitmapData dstBitmapData = null;
		
					try
					{
		
		
		
						// Verifica se bpp (Bits Per Pixel) é 8, 24, ou 32
						int Depth = System.Drawing.Bitmap.GetPixelFormatSize(sourceImage.PixelFormat);
						if (Depth != 8 && Depth != 24 && Depth != 32)
						{
							throw new ArgumentException("Only 8, 24 and 32 bpp images are supported.");
						}
		
						// Recupera a contagem dos componentes de cor
						int cCount = Depth / 8;
		
						System.Drawing.Size baseSize = new System.Drawing.Size(sourceImage.Width, sourceImage.Height);
		
						//verifica se é uma imagem de baixa e precisa redimencionar para melhorar a qualidade
						//e não gerar serrilhamento da imagem
						Int32 maxSize = Math.Max(sourceImage.Width, sourceImage.Height);
		
							baseSize = new System.Drawing.Size((Int32)((float)sourceImage.Width * percent), (Int32)((float)sourceImage.Height * percent));
		
						StartImage = new Bitmap(baseSize.Width, baseSize.Height, sourceImage.PixelFormat);
						StartImage.SetResolution(sourceImage.HorizontalResolution, sourceImage.VerticalResolution);
		
						//Cria o objeto de desenho e fundo branco
						Graphics g = Graphics.FromImage(StartImage);
						g.SmoothingMode = SmoothingMode.AntiAlias;
						g.InterpolationMode = InterpolationMode.HighQualityBicubic;
						g.PixelOffsetMode = PixelOffsetMode.HighQuality;
						g.DrawImage(sourceImage, new Rectangle(-1, -1, baseSize.Width + 1, baseSize.Height + 1), 0, 0, sourceImage.Width, sourceImage.Height, GraphicsUnit.Pixel);
						g.Dispose();
						// Bloqueia a imagem de origem e copia para o array de bytes e libera a imagem de origem
						srcBitmapData = StartImage.LockBits(new Rectangle(0, 0, StartImage.Width, StartImage.Height), ImageLockMode.ReadOnly, StartImage.PixelFormat);
						srcPixels = new byte[StartImage.Width * StartImage.Height * (Depth / 8)];
						Marshal.Copy(srcBitmapData.Scan0, srcPixels, 0, srcPixels.Length);
						StartImage.UnlockBits(srcBitmapData);
						srcBitmapData = null;
		
						//Cria o array de bytes da imagem de destino
						dstPixels = new Byte[srcPixels.Length];
		
						//Preenche todo o quadro com a cor de fundo selecionada
						Int32 index = ((1 * StartImage.Width) + 1) * cCount; //index = ((Y * Width) + X) * cCount
						do
						{
							if (Depth == 32) // Para 32 bpp define Red, Green, Blue e Alpha
							{
								dstPixels[index++] = backgroundColor.B;
								dstPixels[index++] = backgroundColor.G;
								dstPixels[index++] = backgroundColor.R;
								dstPixels[index++] = backgroundColor.A; // a
							}
							if (Depth == 24) // Para 24 bpp define Red, Green e Blue
							{
								dstPixels[index++] = backgroundColor.B;
								dstPixels[index++] = backgroundColor.G;
								dstPixels[index++] = backgroundColor.R;
							}
							if (Depth == 8)
							// Para 8 bpp define o valor da cor (Red, Green and Blue como sendo a mesma coisa)
							{
								dstPixels[index++] = backgroundColor.B;
							}
		
						} while (index < srcPixels.Length);
						//Calcula a amplitude máxima possível para a imagem e multiplica pelo fator desejados
						double amp = 0;
						double ang = Math.PI * 0.5;
						for (Int32 a = 0; a < StartImage.Height; a++)
						{
							int y = (int)((StartImage.Height / 2) - amp * Math.Sin(ang));
							if ((y < 0) || (y > StartImage.Height))
								break;
							amp = a;
						}
						amp = (amp - 2) * (factor < -1 ? -1 : (factor > 1 ? 1 : factor));
						//Define variáveis que calcula os pontos de corte (se houver)
						Int32 x1, y1, x2, y2;
						x1 = StartImage.Width;
						y1 = StartImage.Height;
		
		
						x2 = 0;
						y2 = 0;
		
						//Copia pixel a pixel para as novas posições
						index = ((1 * StartImage.Width) + 1) * cCount;
						do
						{
		
							Int32 y = (Int32)((index / cCount) / StartImage.Width);
							Int32 x = (index / cCount) - (y * StartImage.Width);
		
							System.Drawing.Point pt = NewPoint(new System.Drawing.Point(x, y), StartImage.Width, StartImage.Height, amp, factor < 0);
		
							//Valores para crop
							if (factor >= 0)
							{
								if (x == StartImage.Width / 2)
								{
									if (pt.Y < y1)
										y1 = pt.Y;
		
									if (pt.Y > y2)
										y2 = pt.Y;
								}
		
								if (y == StartImage.Height / 2)
								{
									if (pt.X < x1)
										x1 = pt.X;
		
									if (pt.X > x2)
										x2 = pt.X;
								}
							}
							else
							{
								if ((x == 1) && (y == 1))
								{
									y1 = pt.Y;
									x1 = pt.X;
								}
		
								if ((x == StartImage.Width - 1) && (y == StartImage.Height - 1))
								{
									y2 = pt.Y;
									x2 = pt.X;
								}
							}
		
							//Indice de bytes onde será aplicada o pixel
							Int32 dstIndex = ((pt.Y * StartImage.Width) + pt.X) * cCount;
		
							if (Depth == 32)
							{
								dstPixels[dstIndex] = srcPixels[index++];
								dstPixels[dstIndex + 1] = srcPixels[index++];
								dstPixels[dstIndex + 2] = srcPixels[index++];
								dstPixels[dstIndex + 3] = srcPixels[index++]; // a
							}
							if (Depth == 24)
							{
								dstPixels[dstIndex] = srcPixels[index++];
								dstPixels[dstIndex + 1] = srcPixels[index++];
								dstPixels[dstIndex + 2] = srcPixels[index++];
							}
							if (Depth == 8)
							{
								dstPixels[dstIndex] = srcPixels[index++];
							}
		
						} while (index < srcPixels.Length);
		
						//Cria a nova imagem com base no array de bytes previamente criado
						NewImage = new Bitmap(StartImage.Width, StartImage.Height, StartImage.PixelFormat);
						NewImage.SetResolution(StartImage.HorizontalResolution, StartImage.VerticalResolution);
						dstBitmapData = NewImage.LockBits(new Rectangle(0, 0, StartImage.Width, StartImage.Height), ImageLockMode.WriteOnly, StartImage.PixelFormat);
						Marshal.Copy(dstPixels, 0, dstBitmapData.Scan0, dstPixels.Length);
						NewImage.UnlockBits(dstBitmapData);
		
						/*
						 // Para efeito de visualização, desenha o quadrado onde será realizado o corte
						 Graphics g2 = Graphics.FromImage(NewImage);
						 g2.SmoothingMode = SmoothingMode.AntiAlias;
						 g2.InterpolationMode = InterpolationMode.HighQualityBicubic;
						 g2.PixelOffsetMode = PixelOffsetMode.HighQuality;
						 g2.DrawRectangle(new Pen(new SolidBrush(Color.Red), 3), new Rectangle(x1, y1, x2 - x1, y2 - y1));
						 g2.Dispose();*/
		
						//Gera a imagem final, com crop ou coo o redimencionamento real
						Bitmap FinalImage = new Bitmap(sourceImage.Width, sourceImage.Height, StartImage.PixelFormat);
						NewImage.SetResolution(StartImage.HorizontalResolution, StartImage.VerticalResolution);
		
						Graphics g1 = Graphics.FromImage(FinalImage);
						g1.SmoothingMode = SmoothingMode.AntiAlias;
						g1.InterpolationMode = InterpolationMode.HighQualityBicubic;
						g1.PixelOffsetMode = PixelOffsetMode.HighQuality;
		
						//Realiza o corte se estiver habilitado o corte automático e houver necessidade de corte
						if ((autoCrop) && ((x1 > 0) || (y1 > 0) || (x2 < NewImage.Height) || (y2 < NewImage.Height)) && false)
						{
							Rectangle cropRect = new Rectangle(x1, y1, x2 - x1, y2 - y1);
							g1.DrawImage(NewImage, new Rectangle(-1, -1, FinalImage.Width + 1, FinalImage.Height + 1), cropRect.X, cropRect.Y, cropRect.Width, cropRect.Height, GraphicsUnit.Pixel);
						}
						else
						{
							g1.DrawImage(NewImage, new Rectangle(-1, -1, FinalImage.Width + 1, FinalImage.Height + 1), 0, 0, NewImage.Width, NewImage.Height, GraphicsUnit.Pixel);
						}
		
						g1.Dispose();
						g1 = null;
		
						NewImage = null;
						return FinalImage;
					}
					finally
					{
						srcBitmapData = null;
						srcPixels = null;
						dstPixels = null;
						dstBitmapData = null;
					}
		
				}
		
				private static System.Drawing.Point NewPoint(System.Drawing.Point AtualPoint, Int32 Width, Int32 Height, double Aplitude, Boolean inverse)
				{
					System.Drawing.Point uP = AtualPoint;
		
					int pY, pX;
					double aY, aX;
		
					aY = aX = 0;
		
					double angX = Math.PI * 1 * (double)uP.X / (double)Width;
					double caX = Aplitude * ((((double)Height / 2F) - (double)uP.Y) / ((double)Height / 2F));
		
					double angY = Math.PI * 1 * (double)uP.Y / (double)Height;
					double caY = Aplitude * ((((double)Width / 2F) - (double)uP.X) / ((double)Width / 2F));
		
					if (inverse)
					{
						double iAng = Math.PI * -1 * 0.5;
						aX = (caX * Math.Sin(iAng));
						aY = (caY * Math.Sin(iAng));
					}
		
					pY = (int)(uP.Y + aX + caX * Math.Sin(angX));
					pX = (int)(uP.X + aY + caY * Math.Sin(angY));
		
					return new System.Drawing.Point(pX, pY);
		
				}
		
				private void pictureBox5_Click(object sender, EventArgs e)
				{
		
				}
			}
		}