DL_Viewer build up - 2

日 18 8月 2019

Day2 : Design the view / functions.

Day1 Achievement.

First view


Design the functions.

  • Again, what to make as DL_Viewer? Raughly designed.
  • Positioning DL_Viewer as red-colored below. design

Design the view next.

Now focusing on a view for one image.
After, I will consider about multi-displaying images or some kind of summary result, etc.

No item requirements Achievement
1 Displaying Image If whole image is visible? Or selectable to pinch in-out? Default image cotroll setting with Grid layout, which is enough for resize behaviour.
2 Choose directory Add directory to browse, using directory control. Done. (It was easy.)
3 Annotation/label Info Draw rectangle, and show label. Done wih pure C# libs, not using OpenCVSharp.
4 Viewer improvement Sort for view order.
View position, and its' controller.
Set Slider for view control.
5 Detailed Information Show detailed information for one image displaying. TreeView Control to show those multiple objects.
6 Folder control It's bothersome to choose 2 folders one by one. Something like shortcut will be. ListView to change simulteneously.

Implementation

  1. Displaying Image

    • It is resized by default, and it's ok for me now.
    • For about layout, grid layout.
      • It is not so complexed, but can place parts as a certain degree.
    • TBD: Grid Layout effect.
  2. Choose directory

    • Add directory to browse, using directory control.

      ```cs private void MenuItem_Click(object sender, RoutedEventArgs e) { FolderBrowserDialog fbd = new FolderBrowserDialog();

      fbd.Description = "Specify the folder to explore.";
      fbd.RootFolder = Environment.SpecialFolder.Desktop;
      fbd.SelectedPath = @"E:\070_data";
      fbd.ShowNewFolderButton = true;
      
      DialogResult dres = fbd.ShowDialog();
      if (dres == System.Windows.Forms.DialogResult.OK)
      {
          files = Directory.GetFiles(fbd.SelectedPath, "*.JPG").Concat(Directory.GetFiles(fbd.SelectedPath, "*.JPEG")).ToArray();
          ind_files = 0;
          UpdateImage(0);
      }
      fbd.Dispose();
      

      } `` * When pressOK, it make list of.JPGand.JPEGfiles. * Added this code withMenuItem`, but this is ok with other controlls, such like button.

  3. Annotation/label Info

    1. Draw rectangle of annotation.

      • There are many Bitmap containers on C#.
      • My solution,
        1. Load image
          • System.Windows.Media.Imaging.BitmapImage
        2. Convert to Bgr24 type.
        3. Copy to WriteableBitmap
          • System.Windows.Media.Imaging.WriteableBitmap.
        4. Modify
          • by Lock(), direct memory access, Unlock().
          • use unsafe{} block with "allow execute unsafe code" project option.
      • Relative code are velow.

        ```cpp // load image var source = new BitmapImage(); source.BeginInit(); source.UriSource = new Uri("file://" + files[ind_files]); source.EndInit();

        // convert to Bgr24 Type FormatConvertedBitmap source_bgr24 = new FormatConvertedBitmap(source, PixelFormats.Bgr24, null, 0);//Correspond to monochrome images.

        // Copy to WriteableBitmap WriteableBitmap writeable_image = new WriteableBitmap(source_bgr24);

        // Modify writeable_image.Lock(); unsafe { int byte_per_pixel = 3;//When Bgr24

        // Get a pointer to the back buffer.
        int pBackBuffer = (int)bmp.BackBuffer;
        
        // direct memory access
        // jj: loop variable for y axis
        // ii: loop variable for x axis
        *((int*)(pBackBuffer + bmp.BackBufferStride * jj + ii * byte_per_pixel + 0)) = (byte)0;
        *((int*)(pBackBuffer + bmp.BackBufferStride * jj + ii * byte_per_pixel + 1)) = (byte)0;
        *((int*)(pBackBuffer + bmp.BackBufferStride * jj + ii * byte_per_pixel + 2)) = (byte)255;// make dot(x, y) = (ii, jj) to red.
        

        } writeable_image.Unlock(); ```

        • To do this, it is good as simple just using standard C#, without OpenCVSharp etc.
    2. XML parser

      • I use below for parsing xml document which has coordinates and labels.

        cpp using System.Xml.Linq;//for XDocument xml = null; try { xml = XDocument.Load(file path).Element("Top node for start seeking"); } catch(FileNotFoundException) { //xml file missing label1.Content = "xml file missing"; } if (xml != null) { foreach (var row in xml.Elements("2nd node to loop")) { something_X = row.Element("3rd node to get info").Value; } } 4. Viewer improvement

    3. View position, and its' controller.

      • Choose Slider Cotrol to expolore files.
      • Bindings
        • It needs files.length must be changeable after specifying the annotation folder.
        • So it needs transform the value range from 0-1 to 0-(files.Length-1).
      • Ideal solution
        • Use Binding.Converter property, with data type of System.Windows.Data.IValueConverter.
      • My solution, Binding tricks
        • Bind Slider and TestBox.
        • Set Slider's Maximum="1", so the value range is 0 to 1.
        • I want to show image no which is 0 to files.Length - 1, on Label2.
        • Then I use trick,
          • Hide TestBox
          • update Labels when Slider changed. ```cpp private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) { int ind_jump = (int)(e.NewValue * (files.Length - 1) + 0.5); label2.Content = ind_jump;
            UpdateImage(ind_jump - ind_files);
            

            } ``` * UpdateImage() is the helper function to update image and write rectangles when xml exists. (I pass to explain here.) 1. Sort for view order. * I pass this function. * This will be done after Inference functions are available.

  4. Detailed Information

    1. Show detailed information for one image displaying.
      • TreeView
        • Replace DataContext as below. ```cpp List treeData = new List();

          TreeViewItem treeNode = null; TreeViewItem treeLeaf = null;

          treeNode = new TreeViewItem(); treeNode.Header = "xml file missing";

          treeLeaf = new TreeViewItem(); treeLeaf.Header = labelFolder + str2;//xml file name of mine. treeNode.Items.Add(treeLeaf);

          treeData.Add(treeNode);

          //treeView 置き換え treeView_labelinfo.DataContext = new { TreeData = treeData }; ```

  5. Folder control

  6. Code for folder control.
    • The instance of ObservableCollection<DataContainer> should be made by auto, by seeking folder name etc. ```cpp public class DataContainer { public Int32 Id { get; set; } public string Title { get; set; } public string ImageFolder { get; set; } public string LabelFolder { get; set; } }

      ObservableCollection ImageNetObjectLocalizationChallenge = new ObservableCollection(); OptWin.listView_DataContainer.DataContext = ImageNetObjectLocalizationChallenge;

      DataContainer item = new DataContainer { Id = 0, Title = "sample", ImageFolder = @"E:\070_data\sample", LabelFolder = @"E:\070_data\sample" }; ImageNetObjectLocalizationChallenge.Add(item);

      item = new DataContainer { Id = 1, Title = "ILSVRC validation", ImageFolder = @"E:\070_data\imagenet_object_localization\ILSVRC\Data\CLS-LOC\val", LabelFolder = @"E:\070_data\imagenet_object_localization\ILSVRC\Annotations\CLS-LOC\val" }; ImageNetObjectLocalizationChallenge.Add(item); ```

Achievement

Second view

  • Latest viewer looks.

    • Left : MainWindow
      • Add menu list.
        • Can specify folder one by one.
      • Arrange layout as gridlayout.
      • Add slide bar for browsing.
      • Text box under slide bar is a Binding trics for updating slide bar.
      • Add TreeView for deteiled info.
        • Can show multiple objects by TreeView.
    • Right : OptionWindow
      • Add ListView for manage folders.
      • Add load button to change folder sets.
  • This would be something for browsing data and labels!

Feature Work

  • I will use this by myself, and want to keep updating.
    1. Add the view-function of inference result and its statistics.
    2. Fix that these code are not on ideal MVVM architecture.

social