From c143e560b1f4c8b05ce51a3ca245d220e45670b5 Mon Sep 17 00:00:00 2001
From: Tom Brazier <tom_github@firstsolo.net>
Date: Sun, 28 May 2023 20:48:01 +0100
Subject: When selecting chroma keying, include unsaturated colours for
 overexposed pixels

---
 tracker-pt/module/point_extractor.cpp | 29 ++++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 7 deletions(-)

(limited to 'tracker-pt/module/point_extractor.cpp')

diff --git a/tracker-pt/module/point_extractor.cpp b/tracker-pt/module/point_extractor.cpp
index 17819d78..4a4ac964 100644
--- a/tracker-pt/module/point_extractor.cpp
+++ b/tracker-pt/module/point_extractor.cpp
@@ -111,11 +111,25 @@ void PointExtractor::extract_single_channel(const cv::Mat& orig_frame, int idx,
     cv::mixChannels(&orig_frame, 1, &dest, 1, from_to, 1);
 }
 
-void PointExtractor::filter_single_channel(const cv::Mat& orig_frame, float r, float g, float b, cv::Mat1b& dest)
+void PointExtractor::filter_single_channel(const cv::Mat& orig_frame, float r, float g, float b, bool overexp, cv::Mat1b& dest)
 {
     ensure_channel_buffers(orig_frame);
 
     cv::transform(orig_frame, dest, cv::Mat(cv::Matx13f(b, g, r)));
+
+    // decrease color saturation logic in proportion to key color intensity?
+    if (overexp)
+    {
+        // get the intensity of the key color (i.e. +ve coefficients)
+        cv::Mat1b temp1(orig_frame.rows, orig_frame.cols);
+        cv::transform(orig_frame, temp1, cv::Mat(cv::Matx13f(std::max(b, 0.0f), std::max(g, 0.0f), std::max(r, 0.0f))));
+        // get the intensity of the non-key color (i.e. -ve coefficients)
+        cv::Mat1b temp2(orig_frame.rows, orig_frame.cols);
+        cv::transform(orig_frame, temp2, cv::Mat(cv::Matx13f(std::max(-b, 0.0f), std::max(-g, 0.0f), std::max(-r, 0.0f))));
+        // add non-key color back into the result in proportion to key color intensity
+        cv::multiply(temp1, temp2, temp1, 1.0 / 255);
+        cv::add(dest, temp1, dest);
+    }
 }
 
 void PointExtractor::color_to_grayscale(const cv::Mat& frame, cv::Mat1b& output)
@@ -146,32 +160,33 @@ void PointExtractor::color_to_grayscale(const cv::Mat& frame, cv::Mat1b& output)
     }
     case pt_color_red_chromakey:
     {
-        filter_single_channel(frame, 1, -0.5, -0.5, output);
+        filter_single_channel(frame, 1, -0.5, -0.5, s.chroma_key_overexposed, output);
         break;
     }
     case pt_color_green_chromakey:
     {
-        filter_single_channel(frame, -0.5, 1, -0.5, output);
+        filter_single_channel(frame, -0.5, 1, -0.5, s.chroma_key_overexposed, output);
+
         break;
     }
     case pt_color_blue_chromakey:
     {
-        filter_single_channel(frame, -0.5, -0.5, 1, output);
+        filter_single_channel(frame, -0.5, -0.5, 1, s.chroma_key_overexposed, output);
         break;
     }
     case pt_color_cyan_chromakey:
     {
-        filter_single_channel(frame, -1, 0.5, 0.5, output);
+        filter_single_channel(frame, -1, 0.5, 0.5, s.chroma_key_overexposed, output);
         break;
     }
     case pt_color_yellow_chromakey:
     {
-        filter_single_channel(frame, 0.5, 0.5, -1, output);
+        filter_single_channel(frame, 0.5, 0.5, -1, s.chroma_key_overexposed, output);
         break;
     }
     case pt_color_magenta_chromakey:
     {
-        filter_single_channel(frame, 0.5, -1, 0.5, output);
+        filter_single_channel(frame, 0.5, -1, 0.5, s.chroma_key_overexposed, output);
         break;
     }
     case pt_color_hardware:
-- 
cgit v1.2.3


From 98ab4962ba9a1940b8068af658def92e1fb64011 Mon Sep 17 00:00:00 2001
From: Tom Brazier <tom_github@firstsolo.net>
Date: Tue, 30 May 2023 14:16:26 +0100
Subject: Reduce CPU usage for overexposed chroma key detection

---
 tracker-pt/module/point_extractor.cpp | 34 ++++++++++++++++++++--------------
 1 file changed, 20 insertions(+), 14 deletions(-)

(limited to 'tracker-pt/module/point_extractor.cpp')

diff --git a/tracker-pt/module/point_extractor.cpp b/tracker-pt/module/point_extractor.cpp
index 4a4ac964..f62ea836 100644
--- a/tracker-pt/module/point_extractor.cpp
+++ b/tracker-pt/module/point_extractor.cpp
@@ -11,6 +11,7 @@
 #include "frame.hpp"
 #include "cv/numeric.hpp"
 #include "compat/math.hpp"
+#include "compat/math-imports.hpp"
 
 #include <opencv2/imgproc.hpp>
 
@@ -115,20 +116,26 @@ void PointExtractor::filter_single_channel(const cv::Mat& orig_frame, float r, f
 {
     ensure_channel_buffers(orig_frame);
 
-    cv::transform(orig_frame, dest, cv::Mat(cv::Matx13f(b, g, r)));
-
-    // decrease color saturation logic in proportion to key color intensity?
-    if (overexp)
+    // just filter for colour or also include overexposed regions?
+    if (!overexp)
+        cv::transform(orig_frame, dest, cv::Mat(cv::Matx13f(b, g, r)));
+    else
     {
-        // get the intensity of the key color (i.e. +ve coefficients)
-        cv::Mat1b temp1(orig_frame.rows, orig_frame.cols);
-        cv::transform(orig_frame, temp1, cv::Mat(cv::Matx13f(std::max(b, 0.0f), std::max(g, 0.0f), std::max(r, 0.0f))));
-        // get the intensity of the non-key color (i.e. -ve coefficients)
-        cv::Mat1b temp2(orig_frame.rows, orig_frame.cols);
-        cv::transform(orig_frame, temp2, cv::Mat(cv::Matx13f(std::max(-b, 0.0f), std::max(-g, 0.0f), std::max(-r, 0.0f))));
-        // add non-key color back into the result in proportion to key color intensity
-        cv::multiply(temp1, temp2, temp1, 1.0 / 255);
-        cv::add(dest, temp1, dest);
+        for (int i = 0; i < orig_frame.rows; i++)
+        {
+            cv::Vec3b const* const __restrict orig_ptr = orig_frame.ptr<cv::Vec3b>(i);
+            uint8_t* const __restrict dest_ptr = dest.ptr(i);
+            for (int j = 0; j < orig_frame.cols; j++)
+            {
+                // get the intensity of the key color (i.e. +ve coefficients)
+                uchar blue = orig_ptr[j][0], green = orig_ptr[j][1], red = orig_ptr[j][2];
+                float key = std::max(b, 0.0f) * blue + std::max(g, 0.0f) * green + std::max(r, 0.0f) * red;
+                // get the intensity of the non-key color (i.e. -ve coefficients)
+                float nonkey = std::max(-b, 0.0f) * blue + std::max(-g, 0.0f) * green + std::max(-r, 0.0f) * red;
+                // the result is key color minus non-key color inversely weighted by key colour intensity
+                dest_ptr[j] = std::max(0.0f, std::min(255.0f, key - (255.0f - key) / 255.0f * nonkey));
+            }
+        }
     }
 }
 
@@ -166,7 +173,6 @@ void PointExtractor::color_to_grayscale(const cv::Mat& frame, cv::Mat1b& output)
     case pt_color_green_chromakey:
     {
         filter_single_channel(frame, -0.5, 1, -0.5, s.chroma_key_overexposed, output);
-
         break;
     }
     case pt_color_blue_chromakey:
-- 
cgit v1.2.3


From 0081061e580c4933b0c7731496916df2cfc0a95c Mon Sep 17 00:00:00 2001
From: Tom Brazier <tom_github@firstsolo.net>
Date: Wed, 31 May 2023 15:09:16 +0100
Subject: Added a slider to control the strength of the color matching for
 chroma key

---
 tracker-pt/FTNoIR_PT_Controls.ui        | 449 +++++++++++++++++---------------
 tracker-pt/ftnoir_tracker_pt_dialog.cpp |  22 +-
 tracker-pt/ftnoir_tracker_pt_dialog.h   |   2 +-
 tracker-pt/lang/nl_NL.ts                |   4 +
 tracker-pt/lang/ru_RU.ts                |   4 +
 tracker-pt/lang/stub.ts                 |   4 +
 tracker-pt/lang/zh_CN.ts                |   4 +
 tracker-pt/module/point_extractor.cpp   |  18 +-
 tracker-pt/pt-settings.hpp              |   1 +
 9 files changed, 288 insertions(+), 220 deletions(-)

(limited to 'tracker-pt/module/point_extractor.cpp')

diff --git a/tracker-pt/FTNoIR_PT_Controls.ui b/tracker-pt/FTNoIR_PT_Controls.ui
index fc1e0392..02e696e3 100644
--- a/tracker-pt/FTNoIR_PT_Controls.ui
+++ b/tracker-pt/FTNoIR_PT_Controls.ui
@@ -10,7 +10,7 @@
     <x>0</x>
     <y>0</y>
     <width>413</width>
-    <height>604</height>
+    <height>628</height>
    </rect>
   </property>
   <property name="sizePolicy">
@@ -79,53 +79,86 @@
           <string>Camera settings</string>
          </property>
          <layout class="QGridLayout" name="gridLayout_2">
-          <item row="4" column="1">
-           <widget class="QCheckBox" name="use_mjpeg">
+          <item row="11" column="1">
+           <widget class="QCheckBox" name="chroma_key_overexposed">
             <property name="text">
              <string/>
             </property>
            </widget>
           </item>
-          <item row="3" column="0">
-           <widget class="QLabel" name="label_37">
+          <item row="5" column="0">
+           <widget class="QLabel" name="label_4">
             <property name="sizePolicy">
              <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
               <horstretch>0</horstretch>
               <verstretch>0</verstretch>
              </sizepolicy>
             </property>
+            <property name="cursor">
+             <cursorShape>WhatsThisCursor</cursorShape>
+            </property>
+            <property name="toolTip">
+             <string>This should be 56° or 76° for the PS3 Eye, dependent upon the physical lens setting. It's only neccessary to get position correspond to real-world values.</string>
+            </property>
             <property name="text">
-             <string>FPS</string>
+             <string>Diagonal field of view</string>
             </property>
-            <property name="buddy">
-             <cstring>fps_spin</cstring>
+           </widget>
+          </item>
+          <item row="6" column="0">
+           <widget class="QLabel" name="label_5">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="text">
+             <string>Dynamic pose (for caps only, never clips)</string>
             </property>
            </widget>
           </item>
-          <item row="1" column="1">
-           <widget class="QSpinBox" name="res_x_spin">
+          <item row="9" column="0">
+           <widget class="QLabel" name="label_12">
             <property name="sizePolicy">
-             <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+             <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
               <horstretch>0</horstretch>
               <verstretch>0</verstretch>
              </sizepolicy>
             </property>
+            <property name="cursor">
+             <cursorShape>WhatsThisCursor</cursorShape>
+            </property>
             <property name="toolTip">
-             <string>Desired capture width</string>
+             <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;For LEDs, 'Natural' is the fastest grayscale mode thanks to optimized SIMD code. Color key allows to track regular pieces of colored paper.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
             </property>
-            <property name="suffix">
-             <string> px</string>
+            <property name="text">
+             <string>Color channels used</string>
             </property>
-            <property name="maximum">
-             <number>2000</number>
+           </widget>
+          </item>
+          <item row="8" column="1">
+           <widget class="QPushButton" name="camera_settings">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
             </property>
-            <property name="singleStep">
-             <number>10</number>
+            <property name="text">
+             <string>Open</string>
             </property>
            </widget>
           </item>
-          <item row="5" column="0">
-           <widget class="QLabel" name="label_4">
+          <item row="4" column="1">
+           <widget class="QCheckBox" name="use_mjpeg">
+            <property name="text">
+             <string/>
+            </property>
+           </widget>
+          </item>
+          <item row="4" column="0">
+           <widget class="QLabel" name="label_13">
             <property name="sizePolicy">
              <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
               <horstretch>0</horstretch>
@@ -136,29 +169,78 @@
              <cursorShape>WhatsThisCursor</cursorShape>
             </property>
             <property name="toolTip">
-             <string>This should be 56° or 76° for the PS3 Eye, dependent upon the physical lens setting. It's only neccessary to get position correspond to real-world values.</string>
+             <string>Enable MJPEG compression for high-speed cameras other than the PS3 Eye. Windows only.</string>
             </property>
             <property name="text">
-             <string>Diagonal field of view</string>
+             <string>MJPEG compression</string>
             </property>
            </widget>
           </item>
-          <item row="3" column="1">
-           <widget class="QSpinBox" name="fps_spin">
+          <item row="3" column="0">
+           <widget class="QLabel" name="label_37">
             <property name="sizePolicy">
-             <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+             <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
               <horstretch>0</horstretch>
               <verstretch>0</verstretch>
              </sizepolicy>
             </property>
-            <property name="toolTip">
-             <string>Desired capture framerate</string>
+            <property name="text">
+             <string>FPS</string>
+            </property>
+            <property name="buddy">
+             <cstring>fps_spin</cstring>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="0">
+           <widget class="QLabel" name="label_36">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="text">
+             <string>Width</string>
+            </property>
+           </widget>
+          </item>
+          <item row="11" column="0">
+           <widget class="QLabel" name="label_16">
+            <property name="text">
+             <string>Chroma key includes overexposed pixels</string>
+            </property>
+           </widget>
+          </item>
+          <item row="8" column="0">
+           <widget class="QLabel" name="label_9">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="text">
+             <string>Camera settings (when available)</string>
+            </property>
+           </widget>
+          </item>
+          <item row="7" column="1">
+           <widget class="QSpinBox" name="init_phase_timeout">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
             </property>
             <property name="suffix">
-             <string> Hz</string>
+             <string> ms</string>
+            </property>
+            <property name="minimum">
+             <number>50</number>
             </property>
             <property name="maximum">
-             <number>2000</number>
+             <number>5000</number>
             </property>
            </widget>
           </item>
@@ -175,21 +257,30 @@
             </property>
            </widget>
           </item>
-          <item row="8" column="1">
-           <widget class="QPushButton" name="camera_settings">
+          <item row="1" column="1">
+           <widget class="QSpinBox" name="res_x_spin">
             <property name="sizePolicy">
              <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
               <horstretch>0</horstretch>
               <verstretch>0</verstretch>
              </sizepolicy>
             </property>
-            <property name="text">
-             <string>Open</string>
+            <property name="toolTip">
+             <string>Desired capture width</string>
+            </property>
+            <property name="suffix">
+             <string> px</string>
+            </property>
+            <property name="maximum">
+             <number>2000</number>
+            </property>
+            <property name="singleStep">
+             <number>10</number>
             </property>
            </widget>
           </item>
-          <item row="2" column="0">
-           <widget class="QLabel" name="label_41">
+          <item row="7" column="0">
+           <widget class="QLabel" name="label_6">
             <property name="sizePolicy">
              <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
               <horstretch>0</horstretch>
@@ -197,7 +288,7 @@
              </sizepolicy>
             </property>
             <property name="text">
-             <string>Height</string>
+             <string>Dynamic pose timeout</string>
             </property>
            </widget>
           </item>
@@ -214,44 +305,51 @@
             </property>
            </widget>
           </item>
-          <item row="7" column="1">
-           <widget class="QSpinBox" name="init_phase_timeout">
+          <item row="0" column="0">
+           <widget class="QLabel" name="label_2">
             <property name="sizePolicy">
-             <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+             <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
               <horstretch>0</horstretch>
               <verstretch>0</verstretch>
              </sizepolicy>
             </property>
-            <property name="suffix">
-             <string> ms</string>
+            <property name="text">
+             <string>Device</string>
             </property>
-            <property name="minimum">
-             <number>50</number>
+            <property name="buddy">
+             <cstring>camdevice_combo</cstring>
             </property>
-            <property name="maximum">
-             <number>5000</number>
+           </widget>
+          </item>
+          <item row="2" column="0">
+           <widget class="QLabel" name="label_41">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="text">
+             <string>Height</string>
             </property>
            </widget>
           </item>
-          <item row="5" column="1">
-           <widget class="QSpinBox" name="fov">
+          <item row="3" column="1">
+           <widget class="QSpinBox" name="fps_spin">
             <property name="sizePolicy">
              <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
               <horstretch>0</horstretch>
               <verstretch>0</verstretch>
              </sizepolicy>
             </property>
-            <property name="suffix">
-             <string>°</string>
-            </property>
-            <property name="prefix">
-             <string/>
+            <property name="toolTip">
+             <string>Desired capture framerate</string>
             </property>
-            <property name="minimum">
-             <number>10</number>
+            <property name="suffix">
+             <string> Hz</string>
             </property>
             <property name="maximum">
-             <number>90</number>
+             <number>2000</number>
             </property>
            </widget>
           </item>
@@ -320,29 +418,25 @@
             </item>
            </widget>
           </item>
-          <item row="1" column="0">
-           <widget class="QLabel" name="label_36">
+          <item row="5" column="1">
+           <widget class="QSpinBox" name="fov">
             <property name="sizePolicy">
-             <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+             <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
               <horstretch>0</horstretch>
               <verstretch>0</verstretch>
              </sizepolicy>
             </property>
-            <property name="text">
-             <string>Width</string>
+            <property name="suffix">
+             <string>°</string>
             </property>
-           </widget>
-          </item>
-          <item row="8" column="0">
-           <widget class="QLabel" name="label_9">
-            <property name="sizePolicy">
-             <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
+            <property name="prefix">
+             <string/>
             </property>
-            <property name="text">
-             <string>Camera settings (when available)</string>
+            <property name="minimum">
+             <number>10</number>
+            </property>
+            <property name="maximum">
+             <number>90</number>
             </property>
            </widget>
           </item>
@@ -368,99 +462,45 @@
             </property>
            </widget>
           </item>
-          <item row="9" column="0">
-           <widget class="QLabel" name="label_12">
-            <property name="sizePolicy">
-             <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
-            </property>
-            <property name="cursor">
-             <cursorShape>WhatsThisCursor</cursorShape>
-            </property>
-            <property name="toolTip">
-             <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;For LEDs, 'Natural' is the fastest grayscale mode thanks to optimized SIMD code. Color key allows to track regular pieces of colored paper.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
-            </property>
-            <property name="text">
-             <string>Color channels used</string>
-            </property>
-           </widget>
-          </item>
-          <item row="6" column="0">
-           <widget class="QLabel" name="label_5">
-            <property name="sizePolicy">
-             <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
-            </property>
-            <property name="text">
-             <string>Dynamic pose (for caps only, never clips)</string>
-            </property>
-           </widget>
-          </item>
-          <item row="0" column="0">
-           <widget class="QLabel" name="label_2">
-            <property name="sizePolicy">
-             <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
-            </property>
-            <property name="text">
-             <string>Device</string>
-            </property>
-            <property name="buddy">
-             <cstring>camdevice_combo</cstring>
-            </property>
-           </widget>
-          </item>
-          <item row="7" column="0">
-           <widget class="QLabel" name="label_6">
-            <property name="sizePolicy">
-             <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
-            </property>
-            <property name="text">
-             <string>Dynamic pose timeout</string>
-            </property>
-           </widget>
-          </item>
-          <item row="4" column="0">
-           <widget class="QLabel" name="label_13">
-            <property name="sizePolicy">
-             <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
-            </property>
-            <property name="cursor">
-             <cursorShape>WhatsThisCursor</cursorShape>
-            </property>
-            <property name="toolTip">
-             <string>Enable MJPEG compression for high-speed cameras other than the PS3 Eye. Windows only.</string>
-            </property>
-            <property name="text">
-             <string>MJPEG compression</string>
-            </property>
-           </widget>
-          </item>
           <item row="10" column="0">
-           <widget class="QLabel" name="label_16">
+           <widget class="QLabel" name="label_17">
             <property name="text">
-             <string>Chroma key includes overexposed pixels</string>
+             <string>Chroma key strength</string>
             </property>
            </widget>
           </item>
           <item row="10" column="1">
-           <widget class="QCheckBox" name="chroma_key_overexposed">
-            <property name="text">
-             <string/>
-            </property>
-           </widget>
+           <layout class="QHBoxLayout" name="horizontalLayout">
+            <item>
+             <widget class="QSlider" name="chroma_key_strength_slider">
+              <property name="minimum">
+               <number>5</number>
+              </property>
+              <property name="maximum">
+               <number>40</number>
+              </property>
+              <property name="orientation">
+               <enum>Qt::Horizontal</enum>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QDoubleSpinBox" name="chroma_key_strength_label">
+              <property name="readOnly">
+               <bool>true</bool>
+              </property>
+              <property name="buttonSymbols">
+               <enum>QAbstractSpinBox::NoButtons</enum>
+              </property>
+              <property name="minimum">
+               <double>0.500000000000000</double>
+              </property>
+              <property name="maximum">
+               <double>4.000000000000000</double>
+              </property>
+             </widget>
+            </item>
+           </layout>
           </item>
          </layout>
         </widget>
@@ -616,6 +656,26 @@
             </property>
            </widget>
           </item>
+          <item row="2" column="1">
+           <widget class="QLabel" name="threshold_value_display">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="text">
+             <string/>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="0">
+           <widget class="QLabel" name="label_14">
+            <property name="text">
+             <string>Value</string>
+            </property>
+           </widget>
+          </item>
           <item row="3" column="1">
            <widget class="QDoubleSpinBox" name="mindiam_spin">
             <property name="sizePolicy">
@@ -638,26 +698,6 @@
             </property>
            </widget>
           </item>
-          <item row="2" column="1">
-           <widget class="QLabel" name="threshold_value_display">
-            <property name="sizePolicy">
-             <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
-            </property>
-            <property name="text">
-             <string/>
-            </property>
-           </widget>
-          </item>
-          <item row="2" column="0">
-           <widget class="QLabel" name="label_14">
-            <property name="text">
-             <string>Value</string>
-            </property>
-           </widget>
-          </item>
          </layout>
         </widget>
        </item>
@@ -693,7 +733,7 @@
           <enum>QTabWidget::Rounded</enum>
          </property>
          <property name="currentIndex">
-          <number>0</number>
+          <number>2</number>
          </property>
          <property name="usesScrollButtons">
           <bool>false</bool>
@@ -1649,55 +1689,55 @@ Don't roll or change position.</string>
       <string>Status</string>
      </property>
      <layout class="QGridLayout" name="gridLayout_10">
-      <item row="1" column="0">
-       <widget class="QLabel" name="label_3">
+      <item row="1" column="1">
+       <widget class="QLabel" name="pointinfo_label">
         <property name="sizePolicy">
-         <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+         <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
         <property name="text">
-         <string>Extracted Points:</string>
+         <string/>
         </property>
        </widget>
       </item>
-      <item row="0" column="0">
-       <widget class="QLabel" name="label_38">
+      <item row="0" column="1">
+       <widget class="QLabel" name="caminfo_label">
         <property name="sizePolicy">
-         <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+         <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
         <property name="text">
-         <string>Camera Info:</string>
+         <string/>
         </property>
        </widget>
       </item>
-      <item row="1" column="1">
-       <widget class="QLabel" name="pointinfo_label">
+      <item row="1" column="0">
+       <widget class="QLabel" name="label_3">
         <property name="sizePolicy">
-         <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+         <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
         <property name="text">
-         <string/>
+         <string>Extracted Points:</string>
         </property>
        </widget>
       </item>
-      <item row="0" column="1">
-       <widget class="QLabel" name="caminfo_label">
+      <item row="0" column="0">
+       <widget class="QLabel" name="label_38">
         <property name="sizePolicy">
-         <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+         <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
         <property name="text">
-         <string/>
+         <string>Camera Info:</string>
         </property>
        </widget>
       </item>
@@ -1727,10 +1767,11 @@ Don't roll or change position.</string>
   <tabstop>fps_spin</tabstop>
   <tabstop>use_mjpeg</tabstop>
   <tabstop>fov</tabstop>
-  <tabstop>dynamic_pose</tabstop>
   <tabstop>init_phase_timeout</tabstop>
+  <tabstop>dynamic_pose</tabstop>
   <tabstop>camera_settings</tabstop>
   <tabstop>blob_color</tabstop>
+  <tabstop>chroma_key_overexposed</tabstop>
   <tabstop>auto_threshold</tabstop>
   <tabstop>threshold_slider</tabstop>
   <tabstop>mindiam_spin</tabstop>
@@ -1740,27 +1781,23 @@ Don't roll or change position.</string>
   <tabstop>clip_theight_spin</tabstop>
   <tabstop>clip_bheight_spin</tabstop>
   <tabstop>clip_blength_spin</tabstop>
+  <tabstop>tx_spin</tabstop>
+  <tabstop>ty_spin</tabstop>
+  <tabstop>tz_spin</tabstop>
+  <tabstop>tcalib_button</tabstop>
   <tabstop>cap_length_spin</tabstop>
   <tabstop>cap_width_spin</tabstop>
   <tabstop>cap_height_spin</tabstop>
   <tabstop>m1x_spin</tabstop>
-  <tabstop>m1y_spin</tabstop>
-  <tabstop>m1z_spin</tabstop>
   <tabstop>m2x_spin</tabstop>
+  <tabstop>m1y_spin</tabstop>
   <tabstop>m2y_spin</tabstop>
+  <tabstop>m1z_spin</tabstop>
   <tabstop>m2z_spin</tabstop>
-  <tabstop>tx_spin</tabstop>
-  <tabstop>ty_spin</tabstop>
-  <tabstop>tz_spin</tabstop>
-  <tabstop>tcalib_button</tabstop>
   <tabstop>enable_point_filter</tabstop>
   <tabstop>point_filter_slider</tabstop>
   <tabstop>point_filter_limit_slider</tabstop>
   <tabstop>point_filter_deadzone_slider</tabstop>
-  <tabstop>maxdiam_spin</tabstop>
-  <tabstop>mindiam_spin</tabstop>
-  <tabstop>auto_threshold</tabstop>
-  <tabstop>threshold_slider</tabstop>
  </tabstops>
  <resources>
   <include location="module/tracker_pt.qrc"/>
diff --git a/tracker-pt/ftnoir_tracker_pt_dialog.cpp b/tracker-pt/ftnoir_tracker_pt_dialog.cpp
index f3025a0c..d67f79a7 100644
--- a/tracker-pt/ftnoir_tracker_pt_dialog.cpp
+++ b/tracker-pt/ftnoir_tracker_pt_dialog.cpp
@@ -110,9 +110,15 @@ TrackerDialog_PT::TrackerDialog_PT(const QString& module_name) :
 
     tie_setting(s.blob_color, ui.blob_color);
 
+    tie_setting(s.chroma_key_strength, ui.chroma_key_strength_slider);
+    connect(&s.chroma_key_strength, value_::value_changed<slider_value>(), ui.chroma_key_strength_label,
+            [this] { ui.chroma_key_strength_label->setValue(*s.chroma_key_strength); });
+    ui.chroma_key_strength_label->setValue(*s.chroma_key_strength);
+
     tie_setting(s.chroma_key_overexposed, ui.chroma_key_overexposed);
-    connect(ui.blob_color, &QComboBox::currentTextChanged, this, &TrackerDialog_PT::chroma_key_overexp_enable);
-    chroma_key_overexp_enable("");
+    connect(ui.blob_color, &QComboBox::currentTextChanged, this, &TrackerDialog_PT::chroma_key_controls_enable);
+
+    chroma_key_controls_enable("");
 
     tie_setting(s.threshold_slider, ui.threshold_value_display, [this](const slider_value& val) {
         return threshold_display_text(int(val));
@@ -252,16 +258,18 @@ void TrackerDialog_PT::show_camera_settings()
         (void)video::show_dialog(s.camera_name);
 }
 
-void TrackerDialog_PT::chroma_key_overexp_enable(const QString&)
+void TrackerDialog_PT::chroma_key_controls_enable(const QString&)
 {
+    bool enabled = false;
     QVariant data = ui.blob_color->currentData();
-    if (!data.isValid())
-        ui.chroma_key_overexposed->setEnabled(false);
-    else
+    if (data.isValid())
     {
         pt_color_type blob_color = pt_color_type(data.toInt());
-        ui.chroma_key_overexposed->setEnabled(blob_color >= pt_color_red_chromakey && blob_color <= pt_color_magenta_chromakey);
+        enabled = blob_color >= pt_color_red_chromakey && blob_color <= pt_color_magenta_chromakey;
     }
+    ui.chroma_key_strength_slider->setEnabled(enabled);
+    ui.chroma_key_strength_label->setEnabled(enabled);
+    ui.chroma_key_overexposed->setEnabled(enabled);
 }
 
 void TrackerDialog_PT::trans_calib_step()
diff --git a/tracker-pt/ftnoir_tracker_pt_dialog.h b/tracker-pt/ftnoir_tracker_pt_dialog.h
index ea631949..79cd91bd 100644
--- a/tracker-pt/ftnoir_tracker_pt_dialog.h
+++ b/tracker-pt/ftnoir_tracker_pt_dialog.h
@@ -39,7 +39,7 @@ public slots:
     void poll_tracker_info_impl();
     void set_camera_settings_available(const QString& camera_name);
     void show_camera_settings();
-    void chroma_key_overexp_enable(const QString&);
+    void chroma_key_controls_enable(const QString&);
 
 protected:
     QString threshold_display_text(int threshold_value);
diff --git a/tracker-pt/lang/nl_NL.ts b/tracker-pt/lang/nl_NL.ts
index 33542d79..fc44b0f1 100644
--- a/tracker-pt/lang/nl_NL.ts
+++ b/tracker-pt/lang/nl_NL.ts
@@ -308,6 +308,10 @@ Don&apos;t roll or change position.</source>
         <source>Chroma key includes overexposed pixels</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Chroma key strength</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>pt_impl::TrackerDialog_PT</name>
diff --git a/tracker-pt/lang/ru_RU.ts b/tracker-pt/lang/ru_RU.ts
index 7714689d..7ff4657e 100644
--- a/tracker-pt/lang/ru_RU.ts
+++ b/tracker-pt/lang/ru_RU.ts
@@ -313,6 +313,10 @@ ROLL или X/Y-смещения.</translation>
         <source>Chroma key includes overexposed pixels</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Chroma key strength</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>pt_impl::TrackerDialog_PT</name>
diff --git a/tracker-pt/lang/stub.ts b/tracker-pt/lang/stub.ts
index 3c90c586..3dbe208d 100644
--- a/tracker-pt/lang/stub.ts
+++ b/tracker-pt/lang/stub.ts
@@ -308,6 +308,10 @@ Don&apos;t roll or change position.</source>
         <source>Chroma key includes overexposed pixels</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Chroma key strength</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>pt_impl::TrackerDialog_PT</name>
diff --git a/tracker-pt/lang/zh_CN.ts b/tracker-pt/lang/zh_CN.ts
index 43164b09..3519d719 100644
--- a/tracker-pt/lang/zh_CN.ts
+++ b/tracker-pt/lang/zh_CN.ts
@@ -308,6 +308,10 @@ Don&apos;t roll or change position.</source>
         <source>Chroma key includes overexposed pixels</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Chroma key strength</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>pt_impl::TrackerDialog_PT</name>
diff --git a/tracker-pt/module/point_extractor.cpp b/tracker-pt/module/point_extractor.cpp
index f62ea836..11a12d5e 100644
--- a/tracker-pt/module/point_extractor.cpp
+++ b/tracker-pt/module/point_extractor.cpp
@@ -167,32 +167,38 @@ void PointExtractor::color_to_grayscale(const cv::Mat& frame, cv::Mat1b& output)
     }
     case pt_color_red_chromakey:
     {
-        filter_single_channel(frame, 1, -0.5, -0.5, s.chroma_key_overexposed, output);
+        float non_key_coeff = -0.5 * *s.chroma_key_strength;
+        filter_single_channel(frame, 1, non_key_coeff, non_key_coeff, s.chroma_key_overexposed, output);
         break;
     }
     case pt_color_green_chromakey:
     {
-        filter_single_channel(frame, -0.5, 1, -0.5, s.chroma_key_overexposed, output);
+        float non_key_coeff = -0.5 * *s.chroma_key_strength;
+        filter_single_channel(frame, non_key_coeff, 1, non_key_coeff, s.chroma_key_overexposed, output);
         break;
     }
     case pt_color_blue_chromakey:
     {
-        filter_single_channel(frame, -0.5, -0.5, 1, s.chroma_key_overexposed, output);
+        float non_key_coeff = -0.5 * *s.chroma_key_strength;
+        filter_single_channel(frame, non_key_coeff, non_key_coeff, 1, s.chroma_key_overexposed, output);
         break;
     }
     case pt_color_cyan_chromakey:
     {
-        filter_single_channel(frame, -1, 0.5, 0.5, s.chroma_key_overexposed, output);
+        float non_key_coeff = -1.0 * *s.chroma_key_strength;
+        filter_single_channel(frame, non_key_coeff, 0.5, 0.5, s.chroma_key_overexposed, output);
         break;
     }
     case pt_color_yellow_chromakey:
     {
-        filter_single_channel(frame, 0.5, 0.5, -1, s.chroma_key_overexposed, output);
+        float non_key_coeff = -1.0 * *s.chroma_key_strength;
+        filter_single_channel(frame, 0.5, 0.5, non_key_coeff, s.chroma_key_overexposed, output);
         break;
     }
     case pt_color_magenta_chromakey:
     {
-        filter_single_channel(frame, 0.5, -1, 0.5, s.chroma_key_overexposed, output);
+        float non_key_coeff = -1.0 * *s.chroma_key_strength;
+        filter_single_channel(frame, 0.5, non_key_coeff, 0.5, s.chroma_key_overexposed, output);
         break;
     }
     case pt_color_hardware:
diff --git a/tracker-pt/pt-settings.hpp b/tracker-pt/pt-settings.hpp
index 29bb348f..5d16d973 100644
--- a/tracker-pt/pt-settings.hpp
+++ b/tracker-pt/pt-settings.hpp
@@ -65,6 +65,7 @@ struct pt_settings final : options::opts
     value<bool> auto_threshold { b, "automatic-threshold", true };
     value<pt_color_type> blob_color { b, "blob-color", pt_color_bt709 };
     value<bool> use_mjpeg { b, "use-mjpeg", false };
+    value<slider_value> chroma_key_strength{ b, "chroma-key-strength", { 1.0, 0.5, 4. } };
     value<bool> chroma_key_overexposed{ b, "chroma-key-overexposed", false };
 
     value<slider_value> threshold_slider { b, "threshold-slider", { 128, 0, 255 } };
-- 
cgit v1.2.3


From 51ebc1a7f860341cd170b4fcc5af6680ce77767a Mon Sep 17 00:00:00 2001
From: Tom Brazier <tom_github@firstsolo.net>
Date: Thu, 1 Jun 2023 15:29:16 +0100
Subject: slightly reduce number of lines of code

---
 tracker-pt/module/point_extractor.cpp | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

(limited to 'tracker-pt/module/point_extractor.cpp')

diff --git a/tracker-pt/module/point_extractor.cpp b/tracker-pt/module/point_extractor.cpp
index 11a12d5e..3329fafc 100644
--- a/tracker-pt/module/point_extractor.cpp
+++ b/tracker-pt/module/point_extractor.cpp
@@ -148,6 +148,7 @@ void PointExtractor::color_to_grayscale(const cv::Mat& frame, cv::Mat1b& output)
         return;
     }
 
+    const float half_chr_key_str = *s.chroma_key_strength * 0.5;
     switch (s.blob_color)
     {
     case pt_color_green_only:
@@ -167,38 +168,32 @@ void PointExtractor::color_to_grayscale(const cv::Mat& frame, cv::Mat1b& output)
     }
     case pt_color_red_chromakey:
     {
-        float non_key_coeff = -0.5 * *s.chroma_key_strength;
-        filter_single_channel(frame, 1, non_key_coeff, non_key_coeff, s.chroma_key_overexposed, output);
+        filter_single_channel(frame, 1, -half_chr_key_str, -half_chr_key_str, s.chroma_key_overexposed, output);
         break;
     }
     case pt_color_green_chromakey:
     {
-        float non_key_coeff = -0.5 * *s.chroma_key_strength;
-        filter_single_channel(frame, non_key_coeff, 1, non_key_coeff, s.chroma_key_overexposed, output);
+        filter_single_channel(frame, -half_chr_key_str, 1, -half_chr_key_str, s.chroma_key_overexposed, output);
         break;
     }
     case pt_color_blue_chromakey:
     {
-        float non_key_coeff = -0.5 * *s.chroma_key_strength;
-        filter_single_channel(frame, non_key_coeff, non_key_coeff, 1, s.chroma_key_overexposed, output);
+        filter_single_channel(frame, -half_chr_key_str, -half_chr_key_str, 1, s.chroma_key_overexposed, output);
         break;
     }
     case pt_color_cyan_chromakey:
     {
-        float non_key_coeff = -1.0 * *s.chroma_key_strength;
-        filter_single_channel(frame, non_key_coeff, 0.5, 0.5, s.chroma_key_overexposed, output);
+        filter_single_channel(frame, -*s.chroma_key_strength, 0.5, 0.5, s.chroma_key_overexposed, output);
         break;
     }
     case pt_color_yellow_chromakey:
     {
-        float non_key_coeff = -1.0 * *s.chroma_key_strength;
-        filter_single_channel(frame, 0.5, 0.5, non_key_coeff, s.chroma_key_overexposed, output);
+        filter_single_channel(frame, 0.5, 0.5, -*s.chroma_key_strength, s.chroma_key_overexposed, output);
         break;
     }
     case pt_color_magenta_chromakey:
     {
-        float non_key_coeff = -1.0 * *s.chroma_key_strength;
-        filter_single_channel(frame, 0.5, non_key_coeff, 0.5, s.chroma_key_overexposed, output);
+        filter_single_channel(frame, 0.5, -*s.chroma_key_strength, 0.5, s.chroma_key_overexposed, output);
         break;
     }
     case pt_color_hardware:
-- 
cgit v1.2.3