As shown in the image below, i have a simple WinForms application which has a main Combo-box to the right where in which based on the number of screens I select, I get an equivalent number of dynamically created combo boxes and Picture boxes. In this example I have selected 4.
As shown in the code bellow, I am trying to create a multi threaded process where in which depending on which of the options(of available cameras) I select in the dynamically created combobox then I want to display the image stream in the same index picturebox. For example if I select a camera in the combobox 1, then I want to display it in the Picturebox 1.
private void comboBoxCameraSelection_SelectedIndexChanged(object sender, EventArgs e)
{
panelComboboxes.Controls.Clear();
tableLayoutPanel1.Controls.Clear();
string selectedValue = comboBoxCameraSelection.SelectedIndex.ToString();
int numNewPictureBoxes = Int32.Parse(selectedValue) + 1;
// Set cell border style with a margin of 1 pixel
tableLayoutPanel1.CellBorderStyle = TableLayoutPanelCellBorderStyle.Inset;
for (int i = 0; i < numNewPictureBoxes; i++)
{
numComboBoxes++;
ComboBox newComboBox = new ComboBox();
newComboBox.Name = "comboBox" + numComboBoxes.ToString();
newComboBox.Size = new System.Drawing.Size(100, 21);
newComboBox.Location = new System.Drawing.Point(10, 50 + numComboBoxes * 25);
newComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
newComboBox.Dock = DockStyle.Top;
LoadCameraList(newComboBox);
newComboBox.SelectedIndexChanged += new EventHandler(comboBox_SelectedIndexChanged);
panelComboboxes.Controls.Add(newComboBox);
PictureBox pb = new PictureBox();
pb.SizeMode = PictureBoxSizeMode.StretchImage;
pb.Dock = DockStyle.Fill;
pb.Anchor = AnchorStyles.None;
pb.Margin = new Padding(1); // Add a margin of 1 to the picture box
tableLayoutPanel1.Controls.Add(pb);
}
numComboBoxes = 0;
}
private void comboBox_SelectedIndexChanged(object sender, EventArgs e)
{
ComboBox? comboBox = sender as ComboBox;
if (comboBox != null)
{
int cameraIndex = int.Parse(comboBox.Name.Replace("comboBox", ""));
int selectedItemIndex = comboBox.SelectedIndex;
Debug.WriteLine("Selected camera index: " + cameraIndex + ", Selected item index: " + selectedItemIndex);
PictureBox pb = (PictureBox)tableLayoutPanel1.Controls[cameraIndex-1];
camera = new Thread(() => CaptureCameraCallback(selectedItemIndex-1, pb));
camera.Start();
}
}
private void CaptureCameraCallback(int camInd,PictureBox pictureBox)
{
frame = new Mat();
capture = new VideoCapture(camInd);
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("image/jpeg"));
var apiUrl = "http://192.168.0.136:5000/object_detection";
//capture.Open(2);
while (isCameraRunning == 1)
{
capture.Read(frame);
// Convert the frame to a JPEG image
var buffer = new byte[frame.Width * frame.Height * frame.ElemSize()];
Cv2.ImEncode(".jpg", frame, out buffer);
// Send the JPEG image to the Flask API
var content = new ByteArrayContent(buffer);
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("image/jpeg");
var response = client.PostAsync(apiUrl, content).Result;
var imageData = response.Content.ReadAsByteArrayAsync().Result;
Image img;
using (var stream = new MemoryStream(imageData))
{
img = Image.FromStream(stream);
}
pictureBox.Image = img;
}
}
After running my script I get no errors or any kind of exception. But nothing gets displayed to the pictureboxes.
I believe that I am making a mistake in the comboBox_SelectedIndexChanged
Method, when passing the picture-box. Maybe I'm referencing it wrong?
I hope that the general approach that I am taking is correct and hope someone can help me out...
Thanks!