summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralex <alex@ASUS>2018-11-19 13:41:39 +0100
committeralex <alex@ASUS>2018-11-19 13:41:39 +0100
commit578ba6631120933b7c19c8f553ebcb10ebf3531b (patch)
tree42c64b3a99022cf70caba5f1e42cd918ff56ec22
parent087881211b4634d4b5b38ba1b52f6dcf110d2c2e (diff)
Separate proc into submodules
-rw-r--r--modules/ctrl/src/start.c2
-rw-r--r--modules/ctrl/tmp/Makefile2
-rw-r--r--modules/image/src/img_iface.cpp2
-rw-r--r--modules/menu/src/menu_tui.c2
-rw-r--r--modules/menu/tmp/Makefile2
-rw-r--r--modules/proc/inc/proc_coins.h47
-rw-r--r--modules/proc/inc/proc_coins.hpp59
-rw-r--r--modules/proc/inc/proc_common.h45
-rw-r--r--modules/proc/inc/proc_common.hpp107
-rw-r--r--modules/proc/inc/proc_iface.h (renamed from modules/proc/inc/proc.h)29
-rw-r--r--modules/proc/inc/proc_iface.hpp (renamed from modules/proc/inc/proc.hpp)29
-rw-r--r--modules/proc/inc/proc_label.h50
-rw-r--r--modules/proc/inc/proc_label.hpp62
-rw-r--r--modules/proc/inc/proc_resistor.h49
-rw-r--r--modules/proc/inc/proc_resistor.hpp61
-rw-r--r--modules/proc/src/proc.cpp2538
-rw-r--r--modules/proc/src/proc_coins.cpp137
-rw-r--r--modules/proc/src/proc_common.cpp376
-rw-r--r--modules/proc/src/proc_iface.c185
-rw-r--r--modules/proc/src/proc_label.cpp386
-rw-r--r--modules/proc/src/proc_resistor.cpp983
-rw-r--r--modules/proc/tmp/Makefile116
-rw-r--r--modules/user/src/user_iface.c2
-rw-r--r--modules/user/tmp/Makefile2
24 files changed, 2654 insertions, 2619 deletions
diff --git a/modules/ctrl/src/start.c b/modules/ctrl/src/start.c
index 52ee14b..2a4c18f 100644
--- a/modules/ctrl/src/start.c
+++ b/modules/ctrl/src/start.c
@@ -16,7 +16,7 @@
/* img_iface_load() */
#include "img_iface.h"
/* proc_iface_series() */
- #include "proc.h"
+ #include "proc_iface.h"
/* saved_name*/
#include "save.h"
/* user_iface() */
diff --git a/modules/ctrl/tmp/Makefile b/modules/ctrl/tmp/Makefile
index 8413864..c11f389 100644
--- a/modules/ctrl/tmp/Makefile
+++ b/modules/ctrl/tmp/Makefile
@@ -18,7 +18,7 @@ _ALL = start.o
ALL = $(_ALL) ctrl_mod.o
STRT_INC_IMG = img_iface.h
-STRT_INC_PROC = proc.h
+STRT_INC_PROC = proc_iface.h
STRT_INC_SAVE = save.h
STRT_INC_USR = user_iface.h
STRT_INC = start.h
diff --git a/modules/image/src/img_iface.cpp b/modules/image/src/img_iface.cpp
index a3028a9..6bf33ff 100644
--- a/modules/image/src/img_iface.cpp
+++ b/modules/image/src/img_iface.cpp
@@ -145,7 +145,7 @@ static void img_iface_save_file (void);
/******************************************************************************
- ******* main *****************************************************************
+ ******* global functions *****************************************************
******************************************************************************/
void img_iface_init (void)
{
diff --git a/modules/menu/src/menu_tui.c b/modules/menu/src/menu_tui.c
index 0e93b0f..64e460a 100644
--- a/modules/menu/src/menu_tui.c
+++ b/modules/menu/src/menu_tui.c
@@ -17,7 +17,7 @@
/* printf_share_file() */
#include "about.h"
/* proc_debug */
- #include "proc.h"
+ #include "proc_iface.h"
/* saved_name */
#include "save.h"
/* start_switch() */
diff --git a/modules/menu/tmp/Makefile b/modules/menu/tmp/Makefile
index e017159..3acc26e 100644
--- a/modules/menu/tmp/Makefile
+++ b/modules/menu/tmp/Makefile
@@ -59,7 +59,7 @@ MENUCLUI_INC_DIRS = -I $(INC_DIR) \
MENUTUI_INC_LIBALX = alx_ncur.h
MENUTUI_INC_ABOUT = about.h
MENUTUI_INC_CTRL = start.h
-MENUTUI_INC_PROC = proc.h
+MENUTUI_INC_PROC = proc_iface.h
MENUTUI_INC_SAVE = save.h
MENUTUI_INC_USR = user_iface.h
MENUTUI_INC = menu_tui.h
diff --git a/modules/proc/inc/proc_coins.h b/modules/proc/inc/proc_coins.h
new file mode 100644
index 0000000..68d15a2
--- /dev/null
+++ b/modules/proc/inc/proc_coins.h
@@ -0,0 +1,47 @@
+/******************************************************************************
+ * Copyright (C) 2018 Alejandro Colomar Andrés *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* include guard ********************************************************
+ ******************************************************************************/
+# ifndef VA_PROC_COINS_H
+ # define VA_PROC_COINS_H
+
+
+/******************************************************************************
+ ******* macros ***************************************************************
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* enums ****************************************************************
+ ******************************************************************************/
+ enum Proc_Coins {
+ COINS_OK,
+ COINS_NOK_COINS,
+ COINS_NOK_OVERLAP
+ };
+
+
+/******************************************************************************
+ ******* variables ************************************************************
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* functions ************************************************************
+ ******************************************************************************/
+ int proc_coins (void);
+
+
+/******************************************************************************
+ ******* include guard ********************************************************
+ ******************************************************************************/
+# endif /* proc_coins.h */
+
+
+/******************************************************************************
+ ******* end of file **********************************************************
+ ******************************************************************************/
diff --git a/modules/proc/inc/proc_coins.hpp b/modules/proc/inc/proc_coins.hpp
new file mode 100644
index 0000000..6dbf7b7
--- /dev/null
+++ b/modules/proc/inc/proc_coins.hpp
@@ -0,0 +1,59 @@
+/******************************************************************************
+ * Copyright (C) 2018 Alejandro Colomar Andrés *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* include guard ********************************************************
+ ******************************************************************************/
+# ifndef VA_PROC_COINS_HPP
+ # define VA_PROC_COINS_HPP
+
+
+/******************************************************************************
+ ******* macros ***************************************************************
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* enums ****************************************************************
+ ******************************************************************************/
+ enum Proc_Coins {
+ COINS_OK,
+ COINS_NOK_COINS,
+ COINS_NOK_OVERLAP
+ };
+
+
+/******************************************************************************
+ ******* C wrapper ************************************************************
+ ******************************************************************************/
+extern "C" {
+
+
+/******************************************************************************
+ ******* variables ************************************************************
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* functions ************************************************************
+ ******************************************************************************/
+ int proc_coins (void);
+
+
+/******************************************************************************
+ ******* C wrapper ************************************************************
+ ******************************************************************************/
+} /* extern "C" */
+
+
+/******************************************************************************
+ ******* include guard ********************************************************
+ ******************************************************************************/
+# endif /* proc_coins.hpp */
+
+
+/******************************************************************************
+ ******* end of file **********************************************************
+ ******************************************************************************/
diff --git a/modules/proc/inc/proc_common.h b/modules/proc/inc/proc_common.h
new file mode 100644
index 0000000..e0a6e36
--- /dev/null
+++ b/modules/proc/inc/proc_common.h
@@ -0,0 +1,45 @@
+/******************************************************************************
+ * Copyright (C) 2018 Alejandro Colomar Andrés *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* include guard ********************************************************
+ ******************************************************************************/
+# ifndef VA_PROC_COMMON_H
+ # define VA_PROC_COMMON_H
+
+
+/******************************************************************************
+ ******* macros ***************************************************************
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* enums ****************************************************************
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* variables ************************************************************
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* functions ************************************************************
+ ******************************************************************************/
+ void proc_show_img (void);
+
+ void clock_start (void);
+ void clock_stop (const char *txt);
+
+
+/******************************************************************************
+ ******* include guard ********************************************************
+ ******************************************************************************/
+# endif /* proc_common.h */
+
+
+/******************************************************************************
+ ******* end of file **********************************************************
+ ******************************************************************************/
diff --git a/modules/proc/inc/proc_common.hpp b/modules/proc/inc/proc_common.hpp
new file mode 100644
index 0000000..e5eb1ec
--- /dev/null
+++ b/modules/proc/inc/proc_common.hpp
@@ -0,0 +1,107 @@
+/******************************************************************************
+ * Copyright (C) 2018 Alejandro Colomar Andrés *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* include guard ********************************************************
+ ******************************************************************************/
+# ifndef VA_PROC_COMMON_HPP
+ # define VA_PROC_COMMON_HPP
+
+
+/******************************************************************************
+ ******* macros ***************************************************************
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* enums ****************************************************************
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* C wrapper ************************************************************
+ ******************************************************************************/
+extern "C" {
+
+
+/******************************************************************************
+ ******* variables ************************************************************
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* functions ************************************************************
+ ******************************************************************************/
+ void proc_apply (void);
+ void proc_save_mem (int n);
+ void proc_load_mem (int n);
+ void proc_save_ref (void);
+ void proc_save_file (void);
+
+ void proc_local_max (void);
+ void proc_lines_vertical (void);
+ void proc_median_horizontal (void);
+ void proc_median_vertical (void);
+
+ void proc_pixel_value (int x, int y, unsigned char *val);
+ void proc_ROI (int x, int y, int w, int h);
+ void proc_and_2ref (void);
+ void proc_not (void);
+ void proc_or_2ref (void);
+ void proc_cmp (int cmp);
+ void proc_dilate (int size);
+ void proc_erode (int size);
+ void proc_dilate_erode (int size);
+ void proc_erode_dilate (int size);
+ void proc_smooth (int method, int ksize);
+ void proc_rotate (class cv::RotatedRect *rect);
+ void proc_adaptive_threshold (int method, int type, int ksize);
+ void proc_cvt_color (int method);
+ void proc_distance_transform (void);
+ void proc_threshold (int type, int ksize);
+ void proc_contours (
+ std::vector <std::vector <class cv::Point_ <int>>> *contours,
+ class cv::Mat *hierarchy);
+ void proc_contours_size (
+ std::vector <std::vector <class cv::Point_ <int>>> *contours,
+ double *area,
+ double *perimeter);
+ void proc_bounding_rect (
+ std::vector <class cv::Point_ <int>> *contour,
+ class cv::Rect_ <int> *rect,
+ bool show);
+ void proc_fit_ellipse (
+ std::vector <class cv::Point_ <int>> *contour,
+ class cv::RotatedRect *rect,
+ bool show);
+ void proc_min_area_rect (
+ std::vector <class cv::Point_ <int>> *contour,
+ class cv::RotatedRect *rect,
+ bool show);
+
+ void proc_OCR (int lang, int conf);
+ void proc_zbar (int type);
+
+ void proc_show_img (void);
+
+ void clock_start (void);
+ void clock_stop (const char *txt);
+
+
+/******************************************************************************
+ ******* C wrapper ************************************************************
+ ******************************************************************************/
+} /* extern "C" */
+
+
+/******************************************************************************
+ ******* include guard ********************************************************
+ ******************************************************************************/
+# endif /* proc_common.hpp */
+
+
+/******************************************************************************
+ ******* end of file **********************************************************
+ ******************************************************************************/
diff --git a/modules/proc/inc/proc.h b/modules/proc/inc/proc_iface.h
index 1a379c9..847eca3 100644
--- a/modules/proc/inc/proc.h
+++ b/modules/proc/inc/proc_iface.h
@@ -6,8 +6,8 @@
/******************************************************************************
******* include guard ********************************************************
******************************************************************************/
-# ifndef VA_PROC_H
- # define VA_PROC_H
+# ifndef VA_PROC_IFACE_H
+ # define VA_PROC_IFACE_H
/******************************************************************************
@@ -34,29 +34,6 @@
PROC_DBG_STOP_STEP
};
- enum Proc_Label {
- LABEL_OK,
- LABEL_NOK_LABEL,
- LABEL_NOK_CERDO,
- LABEL_NOK_BCODE,
- LABEL_NOK_PRODUCT,
- LABEL_NOK_PRICE
- };
-
- enum Proc_Coins {
- COINS_OK,
- COINS_NOK_COINS,
- COINS_NOK_OVERLAP
- };
-
- enum Proc_Resistor {
- RESISTOR_OK,
- RESISTOR_NOK_RESISTOR,
- RESISTOR_NOK_BANDS,
- RESISTOR_NOK_STD_VALUE,
- RESISTOR_NOK_TOLERANCE
- };
-
/******************************************************************************
******* variables ************************************************************
@@ -75,7 +52,7 @@
/******************************************************************************
******* include guard ********************************************************
******************************************************************************/
-# endif /* proc.h */
+# endif /* proc_iface.h */
/******************************************************************************
diff --git a/modules/proc/inc/proc.hpp b/modules/proc/inc/proc_iface.hpp
index cfeaf40..f4345a8 100644
--- a/modules/proc/inc/proc.hpp
+++ b/modules/proc/inc/proc_iface.hpp
@@ -6,8 +6,8 @@
/******************************************************************************
******* include guard ********************************************************
******************************************************************************/
-# ifndef VA_PROC_HPP
- # define VA_PROC_HPP
+# ifndef VA_PROC_IFACE_H
+ # define VA_PROC_IFACE_H
/******************************************************************************
@@ -34,29 +34,6 @@
PROC_DBG_STOP_STEP
};
- enum Proc_Label {
- LABEL_OK,
- LABEL_NOK_LABEL,
- LABEL_NOK_CERDO,
- LABEL_NOK_BCODE,
- LABEL_NOK_PRODUCT,
- LABEL_NOK_PRICE
- };
-
- enum Proc_Coins {
- COINS_OK,
- COINS_NOK_COINS,
- COINS_NOK_OVERLAP
- };
-
- enum Proc_Resistor {
- RESISTOR_OK,
- RESISTOR_NOK_RESISTOR,
- RESISTOR_NOK_BANDS,
- RESISTOR_NOK_STD_VALUE,
- RESISTOR_NOK_TOLERANCE
- };
-
/******************************************************************************
******* C wrapper ************************************************************
@@ -87,7 +64,7 @@ extern "C" {
/******************************************************************************
******* include guard ********************************************************
******************************************************************************/
-# endif /* proc.hpp */
+# endif /* proc_iface.h */
/******************************************************************************
diff --git a/modules/proc/inc/proc_label.h b/modules/proc/inc/proc_label.h
new file mode 100644
index 0000000..1792e43
--- /dev/null
+++ b/modules/proc/inc/proc_label.h
@@ -0,0 +1,50 @@
+/******************************************************************************
+ * Copyright (C) 2018 Alejandro Colomar Andrés *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* include guard ********************************************************
+ ******************************************************************************/
+# ifndef VA_PROC_LABEL_H
+ # define VA_PROC_LABEL_H
+
+
+/******************************************************************************
+ ******* macros ***************************************************************
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* enums ****************************************************************
+ ******************************************************************************/
+ enum Proc_Label {
+ LABEL_OK,
+ LABEL_NOK_LABEL,
+ LABEL_NOK_CERDO,
+ LABEL_NOK_BCODE,
+ LABEL_NOK_PRODUCT,
+ LABEL_NOK_PRICE
+ };
+
+
+/******************************************************************************
+ ******* variables ************************************************************
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* functions ************************************************************
+ ******************************************************************************/
+ int proc_label (void);
+
+
+/******************************************************************************
+ ******* include guard ********************************************************
+ ******************************************************************************/
+# endif /* proc_label.h */
+
+
+/******************************************************************************
+ ******* end of file **********************************************************
+ ******************************************************************************/
diff --git a/modules/proc/inc/proc_label.hpp b/modules/proc/inc/proc_label.hpp
new file mode 100644
index 0000000..eb5dd66
--- /dev/null
+++ b/modules/proc/inc/proc_label.hpp
@@ -0,0 +1,62 @@
+/******************************************************************************
+ * Copyright (C) 2018 Alejandro Colomar Andrés *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* include guard ********************************************************
+ ******************************************************************************/
+# ifndef VA_PROC_LABEL_HPP
+ # define VA_PROC_LABEL_HPP
+
+
+/******************************************************************************
+ ******* macros ***************************************************************
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* enums ****************************************************************
+ ******************************************************************************/
+ enum Proc_Label {
+ LABEL_OK,
+ LABEL_NOK_LABEL,
+ LABEL_NOK_CERDO,
+ LABEL_NOK_BCODE,
+ LABEL_NOK_PRODUCT,
+ LABEL_NOK_PRICE
+ };
+
+
+/******************************************************************************
+ ******* C wrapper ************************************************************
+ ******************************************************************************/
+extern "C" {
+
+
+/******************************************************************************
+ ******* variables ************************************************************
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* functions ************************************************************
+ ******************************************************************************/
+ int proc_label (void);
+
+
+/******************************************************************************
+ ******* C wrapper ************************************************************
+ ******************************************************************************/
+} /* extern "C" */
+
+
+/******************************************************************************
+ ******* include guard ********************************************************
+ ******************************************************************************/
+# endif /* proc_label.hpp */
+
+
+/******************************************************************************
+ ******* end of file **********************************************************
+ ******************************************************************************/
diff --git a/modules/proc/inc/proc_resistor.h b/modules/proc/inc/proc_resistor.h
new file mode 100644
index 0000000..8a84c7b
--- /dev/null
+++ b/modules/proc/inc/proc_resistor.h
@@ -0,0 +1,49 @@
+/******************************************************************************
+ * Copyright (C) 2018 Alejandro Colomar Andrés *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* include guard ********************************************************
+ ******************************************************************************/
+# ifndef VA_PROC_RESISTOR_H
+ # define VA_PROC_RESISTOR_H
+
+
+/******************************************************************************
+ ******* macros ***************************************************************
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* enums ****************************************************************
+ ******************************************************************************/
+ enum Proc_Resistor {
+ RESISTOR_OK,
+ RESISTOR_NOK_RESISTOR,
+ RESISTOR_NOK_BANDS,
+ RESISTOR_NOK_STD_VALUE,
+ RESISTOR_NOK_TOLERANCE
+ };
+
+
+/******************************************************************************
+ ******* variables ************************************************************
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* functions ************************************************************
+ ******************************************************************************/
+ int proc_resistor (void);
+
+
+/******************************************************************************
+ ******* include guard ********************************************************
+ ******************************************************************************/
+# endif /* proc_resistor.h */
+
+
+/******************************************************************************
+ ******* end of file **********************************************************
+ ******************************************************************************/
diff --git a/modules/proc/inc/proc_resistor.hpp b/modules/proc/inc/proc_resistor.hpp
new file mode 100644
index 0000000..b086ba6
--- /dev/null
+++ b/modules/proc/inc/proc_resistor.hpp
@@ -0,0 +1,61 @@
+/******************************************************************************
+ * Copyright (C) 2018 Alejandro Colomar Andrés *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* include guard ********************************************************
+ ******************************************************************************/
+# ifndef VA_PROC_RESISTOR_HPP
+ # define VA_PROC_RESISTOR_HPP
+
+
+/******************************************************************************
+ ******* macros ***************************************************************
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* enums ****************************************************************
+ ******************************************************************************/
+ enum Proc_Resistor {
+ RESISTOR_OK,
+ RESISTOR_NOK_RESISTOR,
+ RESISTOR_NOK_BANDS,
+ RESISTOR_NOK_STD_VALUE,
+ RESISTOR_NOK_TOLERANCE
+ };
+
+
+/******************************************************************************
+ ******* C wrapper ************************************************************
+ ******************************************************************************/
+extern "C" {
+
+
+/******************************************************************************
+ ******* variables ************************************************************
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* functions ************************************************************
+ ******************************************************************************/
+ int proc_resistor (void);
+
+
+/******************************************************************************
+ ******* C wrapper ************************************************************
+ ******************************************************************************/
+} /* extern "C" */
+
+
+/******************************************************************************
+ ******* include guard ********************************************************
+ ******************************************************************************/
+# endif /* proc_resistor.hpp */
+
+
+/******************************************************************************
+ ******* end of file **********************************************************
+ ******************************************************************************/
diff --git a/modules/proc/src/proc.cpp b/modules/proc/src/proc.cpp
deleted file mode 100644
index 9238f33..0000000
--- a/modules/proc/src/proc.cpp
+++ /dev/null
@@ -1,2538 +0,0 @@
-/******************************************************************************
- * Copyright (C) 2018 Alejandro Colomar Andrés *
- ******************************************************************************/
-
-
-/******************************************************************************
- ******* headers **************************************************************
- ******************************************************************************/
-/* Standard C ----------------------------------------------------------------*/
- /* pow() */
- #include <cmath>
- /* snprintf() & fflush() */
- #include <cstdio>
- /* strcmp() */
- #include <cstring>
- /* clock_t & clock() & CLOCKS_PER_SEC */
- #include <ctime>
-
-/* Packages ------------------------------------------------------------------*/
- /* openCV */
- #include <opencv2/opencv.hpp>
- /* zbar::ZBAR_EAN13 */
- #include <zbar.h>
-
-/* libalx -------------------------------------------------------------------*/
- /* alx_sscan_fname() */
- #include "alx_input.hpp"
-
-/* Project -------------------------------------------------------------------*/
- /* img_iface_act() */
- #include "img_iface.hpp"
- /* user_iface_log */
- #include "user_iface.hpp"
- /* saved_path */
- #include "save.hpp"
-
-/* Module --------------------------------------------------------------------*/
- #include "proc.hpp"
-
-
-/******************************************************************************
- ******* variables ************************************************************
- ******************************************************************************/
-/* Global --------------------------------------------------------------------*/
- int proc_debug;
- int proc_mode;
-
-/* Static --------------------------------------------------------------------*/
-static char proc_path [FILENAME_MAX];
-static char proc_fail_path [FILENAME_MAX];
-
-
-/******************************************************************************
- ******* static functions *****************************************************
- ******************************************************************************/
-static int proc_label (void);
-static void result_label (int status);
-
-static int proc_coins (void);
-static void result_coins (int status);
-
-static int proc_resistor (void);
-static void result_resistor (int status);
-
-static void proc_apply (void);
-static void proc_save_mem (int n);
-static void proc_load_mem (int n);
-static void proc_save_ref (void);
-static void proc_save_file (void);
-
-static void proc_local_max (void);
-static void proc_lines_vertical (void);
-static void proc_median_horizontal (void);
-static void proc_median_vertical (void);
-
-static void proc_pixel_value (int x, int y, unsigned char *val);
-static void proc_ROI (int x, int y, int w, int h);
-static void proc_and_2ref (void);
-static void proc_not (void);
-static void proc_or_2ref (void);
-static void proc_cmp (int cmp);
-static void proc_dilate (int size);
-static void proc_erode (int size);
-static void proc_dilate_erode (int size);
-static void proc_erode_dilate (int size);
-static void proc_smooth (int method, int ksize);
-static void proc_rotate (class cv::RotatedRect *rect);
-static void proc_adaptive_threshold (int method, int type, int ksize);
-static void proc_cvt_color (int method);
-static void proc_distance_transform (void);
-static void proc_threshold (int type, int ksize);
-static void proc_contours (
- std::vector <std::vector <class cv::Point_ <int>>> *contours,
- class cv::Mat *hierarchy);
-static void proc_contours_size (
- std::vector <std::vector <class cv::Point_ <int>>> *contours,
- double *area,
- double *perimeter);
-static void proc_bounding_rect (
- std::vector <class cv::Point_ <int>> *contour,
- class cv::Rect_ <int> *rect,
- bool show);
-static void proc_fit_ellipse (
- std::vector <class cv::Point_ <int>> *contour,
- class cv::RotatedRect *rect,
- bool show);
-static void proc_min_area_rect (
- std::vector <class cv::Point_ <int>> *contour,
- class cv::RotatedRect *rect,
- bool show);
-
-static void proc_OCR (int lang, int conf);
-static void proc_zbar (int type);
-
-static void proc_show_img (void);
-
-
-/******************************************************************************
- ******* main *****************************************************************
- ******************************************************************************/
-int proc_iface_single (int action)
-{
- int error;
- clock_t time_0;
- clock_t time_1;
- double time_tot;
-
- /* Init timer */
- time_0 = clock();
-
- /* Process */
- switch (action) {
- case PROC_MODE_LABEL:
- error = proc_label();
- break;
- case PROC_MODE_COINS:
- error = proc_coins();
- break;
- case PROC_MODE_RESISTOR:
- error = proc_resistor();
- break;
- }
-
- /* End timer */
- time_1 = clock();
-
- /* Calculate time in seconds */
- time_tot = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
-
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time: %.3lf", time_tot);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
-
- return error;
-}
-
-void proc_iface_series (void)
-{
- bool file_error;
- int num_len;
- char file_basename [FILENAME_MAX];
- char file_ext [80];
- char file_name [FILENAME_MAX];
- bool proc_error;
- char save_error_as [FILENAME_MAX];
-
- switch (proc_mode) {
- case PROC_MODE_LABEL:
- snprintf(proc_path, FILENAME_MAX, "%s", labels_path);
- snprintf(proc_fail_path, FILENAME_MAX, "%s", labels_fail_path);
- snprintf(file_basename, 80, "b");
- num_len = 4;
- snprintf(file_ext, 80, ".BMP");
- break;
- case PROC_MODE_COINS:
- snprintf(proc_path, FILENAME_MAX, "%s", coins_path);
- snprintf(proc_fail_path, FILENAME_MAX, "%s", coins_fail_path);
- snprintf(file_basename, 80, "c");
- num_len = 4;
- snprintf(file_ext, 80, ".png");
- break;
- case PROC_MODE_RESISTOR:
- snprintf(proc_path, FILENAME_MAX, "%s", resistors_path);
- snprintf(proc_fail_path, FILENAME_MAX, "%s", resistors_fail_path);
- snprintf(file_basename, 80, "r");
- num_len = 4;
- snprintf(file_ext, 80, ".png");
- break;
- }
-
- bool wh;
- int i;
- wh = true;
- for (i = 0; wh; i++) {
- snprintf(file_name, FILENAME_MAX, "%s%04i%s",
- file_basename, i, file_ext);
-
- file_error = alx_sscan_fname(proc_path, file_name,
- true, file_name);
-
- if (file_error) {
- wh = false;
- } else {
- errno = 0;
- img_iface_load(proc_path, file_name);
-
- if (!errno) {
- /* Process */
- proc_error = proc_iface_single(proc_mode);
-
- if (proc_error) {
- /* Save failed image into file */
- proc_show_img();
- snprintf(save_error_as, FILENAME_MAX,
- "%s%04i_err%s",
- file_basename, i,
- file_ext);
- save_image_file(proc_fail_path,
- save_error_as);
- }
-
- /* Show log */
- char txt_tmp [80];
- snprintf(txt_tmp, 80, "%04i", i);
- user_iface_show_log(txt_tmp, "Item");
-
- if (proc_debug >= PROC_DBG_STOP_ITEM) {
- getchar();
- }
- } else {
- printf("errno:%i\n", errno);
- }
- }
- }
-}
-
-
-/******************************************************************************
- ******* static functions *****************************************************
- ******************************************************************************/
-static int proc_label (void)
-{
- int status;
-
- double times;
- clock_t time_0;
- clock_t time_1;
-
- std::vector <std::vector <cv::Point_ <int>>> contours;
- class cv::Mat hierarchy;
- class cv::RotatedRect rect;
- int x;
- int y;
- int w;
- int h;
-
- char price [80];
-
- proc_save_mem(0);
- /* Find label (position and angle) */
- {
- /* Measure time */
- time_0 = clock();
-
- proc_cmp(IMG_IFACE_CMP_BLUE);
- proc_smooth(IMGI_SMOOTH_MEDIAN, 7);
-#if 0
- proc_adaptive_threshold(CV_ADAPTIVE_THRESH_MEAN_C,
- CV_THRESH_BINARY, 5);
-#else
- proc_not();
-#endif
- proc_smooth(IMGI_SMOOTH_MEAN, 21);
- proc_threshold(cv::THRESH_BINARY_INV, 2);
- proc_dilate_erode(100);
- proc_contours(&contours, &hierarchy);
-
- /* If no contour is found, error: NOK_LABEL */
- if (!contours.size()) {
- status = LABEL_NOK_LABEL;
- result_label(status);
- return status;
- }
-
- proc_min_area_rect(&(contours[0]), &rect, true);
-
- /* If angle is < -45º, it is taking into acount the incorrect side */
- if (rect.angle < -45.0) {
- int tmp;
- rect.angle += 90.0;
- tmp = rect.size.width;
- rect.size.width = rect.size.height;
- rect.size.height = tmp;
- }
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time0: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Align label and extract green component */
- {
- /* Measure time */
- time_0 = clock();
-
- proc_load_mem(0);
- proc_rotate(&rect);
- proc_cmp(IMG_IFACE_CMP_GREEN);
- proc_save_mem(1);
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time1: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Find "Cerdo" in aligned image */
- {
- /* Measure time */
- time_0 = clock();
-
- x = rect.center.x - (1.05 * rect.size.width / 2);
- if (x < 0) {
- x = 0;
- }
- y = rect.center.y - (1.47 * rect.size.height / 2);
- if (y < 0) {
- y = 0;
- }
- w = rect.size.width / 2;
- h = rect.size.height * 0.20;
- proc_ROI(x, y, w, h);
- proc_threshold(cv::THRESH_BINARY, IMG_IFACE_THR_OTSU);
- proc_erode(1);
- proc_OCR(IMG_IFACE_OCR_LANG_ENG, IMG_IFACE_OCR_CONF_NONE);
-
- /* Compare Label text to "Cerdo". */
- bool cerdo_nok;
- cerdo_nok = strncmp(img_ocr_text, "Cerdo",
- strlen("Cerdo"));
- if (cerdo_nok) {
- status = LABEL_NOK_CERDO;
- result_label(status);
- return status;
- }
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time2: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Read barcode in original image */
- {
- /* Measure time */
- time_0 = clock();
-
- proc_load_mem(0);
- proc_cmp(IMG_IFACE_CMP_GREEN);
- proc_zbar(zbar::ZBAR_EAN13);
-
- /* Check that 1 and only 1 bcode is read. */
- if (zb_codes.n != 1) {
- status = LABEL_NOK_BCODE;
- result_label(status);
- return status;
- }
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time3: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Check product code in barcode */
- {
- /* Measure time */
- time_0 = clock();
-
- bool prod_nok;
- prod_nok = strncmp(zb_codes.arr[0].data, "2301703",
- strlen("2301703"));
- if (prod_nok) {
- status = LABEL_NOK_PRODUCT;
- result_label(status);
- return status;
- }
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time4: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Read price in aligned image (green component) */
- {
- /* Measure time */
- time_0 = clock();
-
- proc_load_mem(1);
-
- x = rect.center.x + (0.33 * rect.size.width / 2);
- y = rect.center.y + (0.64 * rect.size.height / 2);
- w = rect.size.width * 0.225;
- h = rect.size.height * 0.15;
- proc_ROI(x, y, w, h);
- proc_smooth(IMGI_SMOOTH_MEAN, 3);
- proc_threshold(cv::THRESH_BINARY, IMG_IFACE_THR_OTSU);
- proc_dilate_erode(1);
- proc_threshold(cv::THRESH_BINARY, 1);
- proc_OCR(IMG_IFACE_OCR_LANG_DIGITS, IMG_IFACE_OCR_CONF_PRICE);
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time5: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Extract price from barcode */
- {
- /* Measure time */
- time_0 = clock();
-
- if (zb_codes.arr[0].data[8] != '0') {
- snprintf(price, 80, "%c%c.%c%c",
- zb_codes.arr[0].data[8],
- zb_codes.arr[0].data[9],
- zb_codes.arr[0].data[10],
- zb_codes.arr[0].data[11]);
- } else {
- snprintf(price, 80, "%c.%c%c",
- zb_codes.arr[0].data[9],
- zb_codes.arr[0].data[10],
- zb_codes.arr[0].data[11]);
- }
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time6: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Check label price with barcode price */
- {
- /* Measure time */
- time_0 = clock();
-
- bool price_nok;
- price_nok = strncmp(img_ocr_text, price, strlen(price));
- if (price_nok) {
- status = LABEL_NOK_PRICE;
- result_label(status);
- return status;
- }
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time7: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
-
- status = LABEL_OK;
- result_label(status);
- return status;
-}
-
-static void result_label (int status)
-{
- /* Cleanup */
-
- /* Write result into log */
- char result [LOG_LINE_LEN];
- switch (status) {
- case LABEL_OK:
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Label: OK");
- break;
- case LABEL_NOK_LABEL:
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Label: NOK_LABEL");
- break;
- case LABEL_NOK_CERDO:
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Label: NOK_CERDO");
- break;
- case LABEL_NOK_BCODE:
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Label: NOK_BCODE");
- break;
- case LABEL_NOK_PRODUCT:
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Label: NOK_PRODUCT");
- break;
- case LABEL_NOK_PRICE:
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Label: NOK_PRICE");
- break;
- default:
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Label: NOK");
- break;
- }
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
-}
-
-static int proc_coins (void)
-{
- int status;
-
- double times;
- clock_t time_0;
- clock_t time_1;
-
- std::vector <std::vector <cv::Point_ <int>>> contours;
- class cv::Mat hierarchy;
- class cv::RotatedRect rect;
- int x;
- int y;
- int w;
- int h;
-
- struct {
- /* found? */
- bool found;
-
- /* position */
- int x;
- int y;
- } blobs [5];
-
- struct {
- /* found? */
- bool found;
-
- /* blob num */
- int blob;
-
- /* position */
- int x;
- int y;
-
- /* value */
- unsigned char h;
- unsigned char s;
- unsigned char v;
- } bands [5];
-
- char code [6] = {'\0', '\0', '\0', '\0', '\0', '\0'};
- float resistance;
- int tolerance;
-
- int i;
- int j;
-
- proc_save_mem(0);
- /* Find coins */
- {
- /* Measure time */
- time_0 = clock();
-
- proc_cmp(IMG_IFACE_CMP_BLUE);
-// proc_smooth(IMGI_SMOOTH_MEDIAN, 11);
- proc_threshold(cv::THRESH_BINARY_INV, IMG_IFACE_THR_OTSU);
-// proc_threshold(cv::THRESH_BINARY_INV, 100);
- proc_distance_transform();
- proc_local_max();
- proc_dilate(8);
- proc_save_mem(1);
-
- proc_contours(&contours, &hierarchy);
-
- /* If no contour is found, error: NOK_COINS */
- if (!contours.size()) {
- status = COINS_NOK_COINS;
- result_coins(status);
- return status;
- }
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time0: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
-#if 0 /* Align resistor and crop */
- {
- /* Measure time */
- time_0 = clock();
-
- proc_load_mem(0);
- proc_rotate(&rect);
- x = rect.center.x - (0.8 * rect.size.width / 2.0);
- if (x < 0) {
- x = 0;
- }
- y = rect.center.y - (0 * rect.size.height / 2.0);
- if (y < 0) {
- y = 0;
- }
- w = rect.size.width * 0.8;
- h = rect.size.height * 0.3;
- proc_ROI(x, y, w, h);
- proc_save_mem(1);
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time1: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Separate background (BK) and lines (WH) */
- {
- /* Measure time */
- time_0 = clock();
-
- proc_smooth(IMGI_SMOOTH_MEDIAN, 5);
- proc_cvt_color(cv::COLOR_BGR2HSV);
- proc_smooth(IMGI_SMOOTH_MEDIAN, 5);
- proc_save_mem(2);
-
- /* hue */
- proc_cmp(IMG_IFACE_CMP_HUE);
- proc_save_mem(3);
- proc_not();
- proc_threshold(cv::THRESH_TOZERO_INV, 255 - 15);
- proc_threshold(cv::THRESH_TOZERO, 255 - 23);
- proc_threshold(cv::THRESH_BINARY_INV, 1);
- proc_save_mem(4);
-
- /* saturation */
- proc_load_mem(2);
- proc_cmp(IMG_IFACE_CMP_SATURATION);
- proc_save_mem(5);
- proc_threshold(cv::THRESH_TOZERO_INV, 163);
- proc_threshold(cv::THRESH_TOZERO, 50);
- proc_threshold(cv::THRESH_BINARY_INV, 1);
- proc_save_mem(6);
-
- /* value */
- proc_load_mem(2);
- proc_cmp(IMG_IFACE_CMP_VALUE);
- proc_save_mem(7);
- proc_threshold(cv::THRESH_TOZERO_INV, 240);
- proc_threshold(cv::THRESH_TOZERO, 100);
- proc_threshold(cv::THRESH_BINARY_INV, 1);
- proc_save_mem(8);
-
- /* Merge the components: H | S | V */
- proc_save_ref();
- proc_load_mem(6);
- proc_or_2ref();
- proc_save_ref();
- proc_load_mem(4);
- proc_or_2ref();
- proc_dilate_erode(1);
- proc_save_mem(9);
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time2: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Find bands: contours -> rectangles -> positions */
- {
- /* Measure time */
- time_0 = clock();
-
- /* Contours */
- proc_contours(&contours, &hierarchy);
-
- bool bands_nok;
- bands_nok = contours.size() != 4;
- if (bands_nok) {
- status = RESISTOR_NOK_BANDS;
- result_label(status);
- return status;
- }
-
- for (i = 0; i < contours.size(); i++) {
- blobs[i].found = true;
- proc_min_area_rect(&(contours[i]), &rect, true);
- blobs[i].x = rect.center.x;
- blobs[i].y = rect.center.y;
- }
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time3: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
-
- }
- /* Read values of HSV on the center of each band */
- {
- /* Measure time */
- time_0 = clock();
-
- /* Sort blobs into bands (sort x) */
- float tmp_x;
- int tmp_i;
- for (i = 0; i < contours.size(); i++) {
- tmp_x = INFINITY;
- for (j = 0; j < contours.size(); j++) {
- if ((blobs[j].x < tmp_x) && (blobs[j].found)) {
- tmp_x = blobs[j].x;
- tmp_i = j;
- }
- }
- blobs[tmp_i].found = false;
- bands[i].blob = tmp_i;
- bands[i].x = blobs[tmp_i].x;
- bands[i].y = blobs[tmp_i].y;
- }
-
- /* Hue */
- proc_load_mem(3);
- for (i = 0; i < contours.size(); i++) {
- proc_pixel_value(bands[i].x, bands[i].y, &(bands[i].h));
- }
- /* Saturation */
- proc_load_mem(5);
- for (i = 0; i < contours.size(); i++) {
- proc_pixel_value(bands[i].x, bands[i].y, &(bands[i].s));
- }
- /* Value */
- proc_load_mem(7);
- for (i = 0; i < contours.size(); i++) {
- proc_pixel_value(bands[i].x, bands[i].y, &(bands[i].v));
- }
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time4: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
-
- }
- /* Interpret colors */
- {
- /* Measure time */
- time_0 = clock();
-
- for (i = 0; (i < contours.size()) && (i < 5); i++) {
- if (bands[i].s < 100) {
- if (bands[i].v < 50) {
- code[i] = '0';
- } else if (bands[i].v > 200) {
- code[i] = '9';
- } else {
- code[i] = '8';
- }
- } else {
- if (bands[i].h < 20) {
- if (bands[i].v > 220) {
- code[i] = '3';
- } else if (bands[i].v < 100) {
- code[i] = '1';
- } else {
- code[i] = '2';
- }
- } else if (bands[i].h < 50) {
- code[i] = '4';
- } else if (bands[i].h < 93) {
- code[i] = '5';
- } else if (bands[i].h < 127) {
- code[i] = '6';
- } else if (bands[i].h < 161) {
- code[i] = '7';
- } else {
- if (bands[i].v < 100) {
- code[i] = '1';
- } else {
- code[i] = '2';
- }
- }
- }
- }
-
-#if 0
- if (contours.size() == 3) {
- /* Precission band not detected: gold */
- code[3] = '4';
- }
-#endif
-
- /* Write bands' code into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Code: \"%s\"",
- code);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time5: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Calculate resistor value */
- {
- /* Measure time */
- time_0 = clock();
-
- /* Base value */
- int base;
- base = 10 * (code[0] - '0') + (code[1] - '0');
-
- /* Check that base value is a standard value */
- int std_values [12] = {10,12,15,18,22,27,33,39,47,56,68,82};
- bool std_value_nok;
- std_value_nok = true;
- for (i = 0; i < 12; i++) {
- if (base == std_values[i]) {
- std_value_nok = false;
- }
- }
- if (std_value_nok) {
- status = RESISTOR_NOK_STD_VALUE;
- result_label(status);
- return status;
- }
-
- /* Calculate resistance */
- int power;
- power = code[2] - '0';
- resistance = base * pow(10, power);
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time6: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Calculate resistor tolerance */
- {
- /* Measure time */
- time_0 = clock();
-
- switch (code[3]) {
- case '1':
- tolerance = 1;
- break;
- case '2':
- tolerance = 2;
- break;
- case '4':
- tolerance = 5;
- break;
- case '8':
- tolerance = 10;
- break;
- default:
- status = RESISTOR_NOK_TOLERANCE;
- result_label(status);
- return status;
- }
-
- /* Write resistance value into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Resistance: %.2E ± %i% Ohm",
- resistance, tolerance);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time7: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
-#endif
- status = COINS_OK;
- result_coins(status);
- return status;
-}
-
-static void result_coins (int status)
-{
- /* Cleanup */
-
- /* Write result into log */
- char result [LOG_LINE_LEN];
- switch (status) {
- case COINS_OK:
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Coin: OK");
- break;
- case COINS_NOK_COINS:
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Coin: NOK_COINS");
- break;
- case COINS_NOK_OVERLAP:
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Coin: NOK_OVERLAP");
- break;
- default:
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Coin: NOK");
- break;
- }
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
-}
-
-static int proc_resistor_ (void)
-{
- int status;
-
- double times;
- clock_t time_0;
- clock_t time_1;
-
- std::vector <std::vector <cv::Point_ <int>>> contours;
- class cv::Mat hierarchy;
- class cv::RotatedRect rect_rot;
- class cv::Rect_ <int> rect;
- int x;
- int y;
- int w;
- int h;
-
- int bkgd;
-
- struct {
- /* position */
- int x;
- int y;
-
- /* value */
- unsigned char h;
- unsigned char s;
- unsigned char v;
- } bands [5];
-
- char code [6] = {'\0', '\0', '\0', '\0', '\0', '\0'};
- int base;
- float resistance;
- int tolerance;
-
- int i;
- int j;
-
- proc_save_mem(0);
- /* Find resistor (position and angle) */
- {
- /* Measure time */
- time_0 = clock();
-
- /* BGR -> HSV */
- proc_cvt_color(cv::COLOR_BGR2HSV);
- proc_save_mem(19);
-
- proc_cmp(IMG_IFACE_CMP_SATURATION);
- proc_smooth(IMGI_SMOOTH_MEDIAN, 7);
- proc_threshold(cv::THRESH_BINARY, IMG_IFACE_THR_OTSU);
- proc_dilate_erode(10);
- proc_save_mem(1);
- proc_contours(&contours, &hierarchy);
-
- /* If no contour is found, error: NOK_RESISTOR */
- if (!contours.size()) {
- status = RESISTOR_NOK_RESISTOR;
- result_resistor(status);
- return status;
- }
-
- proc_min_area_rect(&(contours[0]), &rect_rot, true);
-
- /* If angle is < -45º, it is taking into acount the incorrect side */
- if (rect_rot.angle < -45.0) {
- rect_rot.angle += 90.0;
- }
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time0: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Align resistor, find its dimensions, and crop */
- {
- /* Measure time */
- time_0 = clock();
-
- /* Align */
- proc_load_mem(19);
- proc_rotate(&rect_rot);
- proc_save_mem(2);
- proc_load_mem(1);
- proc_rotate(&rect_rot);
- proc_save_mem(3);
-
- /* Dimensions */
- proc_contours(&contours, &hierarchy);
- proc_bounding_rect(&(contours[0]), &rect, true);
-
- /* Crop */
- proc_load_mem(2);
- w = rect.width;
- h = rect.height;
- x = rect.x;
- y = rect.y;
- proc_ROI(x, y, w, h);
- proc_save_mem(4);
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time1: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Find backgroung color */
- {
- /* Measure time */
- time_0 = clock();
-
- /* hue */
- uint8_t bkgd_hue;
- proc_cmp(IMG_IFACE_CMP_HUE);
- proc_median_vertical();
- proc_median_horizontal();
- proc_pixel_value(0, 0, &bkgd_hue);
-
- /* saturation */
- uint8_t bkgd_sat;
- proc_load_mem(4);
- proc_cmp(IMG_IFACE_CMP_SATURATION);
- proc_median_vertical();
- proc_median_horizontal();
- proc_pixel_value(0, 0, &bkgd_sat);
-
- if (bkgd_hue < 50) {
- /* Beige */
- bkgd = 0;
- } else {
- /* Blue */
- if ((bkgd_hue <= 90) || (bkgd_sat <= 140)) {
- /* Teal blue */
- bkgd = 1;
- } else if (bkgd_hue >= 105) {
- /* Dark blue */
- bkgd = 2;
- } else {
- /* Normal blue */
- bkgd = 3;
- }
- }
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time2: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Crop more */
- {
- /* Measure time */
- time_0 = clock();
-
- /* Dimensions */
- proc_load_mem(3);
- proc_erode_dilate(rect.height / 1.9 - 9);
- proc_contours(&contours, &hierarchy);
- proc_bounding_rect(&(contours[0]), &rect, true);
-
- /* Crop */
- proc_load_mem(2);
- w = rect.width * 0.9;
- h = rect.height * 0.9;
- x = rect.x + w * (1.0 - 0.9) / 2.0;
- y = rect.y + h * (1.0 - 0.9) / 2.0;
- proc_ROI(x, y, w, h);
- proc_save_mem(4);
-
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time1: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Separate background (BK) and lines (WH) */
- {
- /* Measure time */
- time_0 = clock();
-
- /* hue */
- proc_load_mem(4);
- proc_cmp(IMG_IFACE_CMP_HUE);
- proc_median_vertical();
- proc_save_mem(9);
- switch (bkgd) {
- case 0:
- proc_threshold(cv::THRESH_TOZERO_INV, 20);
- proc_threshold(cv::THRESH_TOZERO, 5);
- break;
- case 1:
- proc_threshold(cv::THRESH_TOZERO_INV, 100);
- proc_threshold(cv::THRESH_TOZERO, 70);
- break;
- case 2:
- proc_threshold(cv::THRESH_TOZERO_INV, 115);
- proc_threshold(cv::THRESH_TOZERO, 105);
- break;
- case 3:
- proc_threshold(cv::THRESH_TOZERO_INV, 110);
- proc_threshold(cv::THRESH_TOZERO, 90);
- break;
- }
- proc_threshold(cv::THRESH_BINARY_INV, 1);
- proc_save_mem(5);
-
- /* saturation */
- proc_load_mem(4);
- proc_cmp(IMG_IFACE_CMP_SATURATION);
- proc_median_vertical();
- proc_save_mem(10);
- switch (bkgd) {
- case 0:
- proc_threshold(cv::THRESH_TOZERO, 100);
- break;
- case 1:
- proc_threshold(cv::THRESH_TOZERO, 95);
- break;
- case 2:
- proc_threshold(cv::THRESH_TOZERO, 200);
- break;
- case 3:
- proc_threshold(cv::THRESH_TOZERO, 130);
- break;
- }
- proc_threshold(cv::THRESH_BINARY_INV, 1);
- proc_save_mem(6);
-
- /* value */
- proc_load_mem(4);
- proc_cmp(IMG_IFACE_CMP_VALUE);
- proc_median_vertical();
- proc_save_mem(11);
- switch (bkgd) {
- case 0:
- proc_threshold(cv::THRESH_TOZERO_INV, 130);
- proc_threshold(cv::THRESH_TOZERO, 65);
- break;
- case 1:
- proc_threshold(cv::THRESH_TOZERO_INV, 155);
- proc_threshold(cv::THRESH_TOZERO, 60);
- break;
- case 2:
- proc_threshold(cv::THRESH_TOZERO_INV, 140);
- proc_threshold(cv::THRESH_TOZERO, 60);
- break;
- case 3:
- proc_threshold(cv::THRESH_TOZERO_INV, 165);
- proc_threshold(cv::THRESH_TOZERO, 45);
- break;
- }
- proc_threshold(cv::THRESH_BINARY_INV, 1);
- proc_save_mem(7);
-
- /* Merge the components: H | S | V */
- proc_save_ref();
- proc_load_mem(5);
- proc_or_2ref();
- proc_save_ref();
- proc_load_mem(6);
- proc_or_2ref();
- proc_dilate_erode(1);
- proc_save_mem(8);
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time3: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Find bands: contours -> rectangles -> ROIs */
- {
- /* Measure time */
- time_0 = clock();
-
- /* Contours */
- proc_contours(&contours, &hierarchy);
-
- bool bands_nok;
- bands_nok = (contours.size() < 3) ||
- (contours.size() > 5);
- if (bands_nok) {
- status = RESISTOR_NOK_BANDS;
- result_resistor(status);
- return status;
- }
-
- /* Band 0 */
- if (contours.size() == 5) {
- proc_bounding_rect(&(contours[4]), &rect, true);
- bands[0].x = rect.x + rect.width / 2.0;
- bands[0].y = rect.y + rect.height / 2.0;
- }
- /* Band 1 */
- if (contours.size() > 3) {
- proc_bounding_rect(&(contours[3]), &rect, true);
- } else {
- proc_bounding_rect(&(contours[2]), &rect, true);
- }
- bands[1].x = rect.x + rect.width / 2.0;
- bands[1].y = rect.y + rect.height / 2.0;
- /* Band 2 */
- if (contours.size() > 3) {
- proc_bounding_rect(&(contours[2]), &rect, true);
- } else {
- proc_bounding_rect(&(contours[1]), &rect, true);
- }
- bands[2].x = rect.x + rect.width / 2.0;
- bands[2].y = rect.y + rect.height / 2.0;
- /* Band 3 */
- if (contours.size() > 3) {
- proc_bounding_rect(&(contours[1]), &rect, true);
- } else {
- proc_bounding_rect(&(contours[0]), &rect, true);
- }
- bands[3].x = rect.x + rect.width / 2.0;
- bands[3].y = rect.y + rect.height / 2.0;
- /* Band 4 */
- if (contours.size() > 3) {
- proc_bounding_rect(&(contours[0]), &rect, true);
- bands[4].x = rect.x + rect.width / 2.0;
- bands[4].y = rect.y + rect.height / 2.0;
- }
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time4: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Read values on the center of each band */
- {
- /* Measure time */
- time_0 = clock();
-
- /* Hue */
- proc_load_mem(9);
- if (contours.size() == 5) {
- proc_pixel_value(bands[0].x, bands[0].y, &(bands[0].h));
- }
- proc_pixel_value(bands[1].x, bands[1].y, &(bands[1].h));
- proc_pixel_value(bands[2].x, bands[2].y, &(bands[2].h));
- proc_pixel_value(bands[3].x, bands[3].y, &(bands[3].h));
- if (contours.size() > 3) {
- proc_pixel_value(bands[4].x, bands[4].y, &(bands[4].h));
- }
-
- /* Saturation */
- proc_load_mem(10);
- if (contours.size() == 5) {
- proc_pixel_value(bands[0].x, bands[0].y, &(bands[0].s));
- }
- proc_pixel_value(bands[1].x, bands[1].y, &(bands[1].s));
- proc_pixel_value(bands[2].x, bands[2].y, &(bands[2].s));
- proc_pixel_value(bands[3].x, bands[3].y, &(bands[3].s));
- if (contours.size() > 3) {
- proc_pixel_value(bands[4].x, bands[4].y, &(bands[4].s));
- }
-
- /* Value */
- proc_load_mem(11);
- if (contours.size() == 5) {
- proc_pixel_value(bands[0].x, bands[0].y, &(bands[0].v));
- }
- proc_pixel_value(bands[1].x, bands[1].y, &(bands[1].v));
- proc_pixel_value(bands[2].x, bands[2].y, &(bands[2].v));
- proc_pixel_value(bands[3].x, bands[3].y, &(bands[3].v));
- if (contours.size() > 3) {
- proc_pixel_value(bands[4].x, bands[4].y, &(bands[4].v));
- }
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time5: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
-
- }
- /* Interpret colors */
- {
- /* Measure time */
- time_0 = clock();
-
- if (contours.size() == 5) {
- i = 0;
- } else {
- code[0] = '0';
- i = 1;
- }
- int loop_lim;
- if (contours.size() > 3) {
- loop_lim = 5;
- } else {
- code[4] = 'n';
- loop_lim = 4;
- }
- for (; i < loop_lim; i++) {
- if (bands[i].v < 24) {
- code[i] = '0';
- } else if (bands[i].v < 28) {
- if ((bands[i].h < 90) || (bands[i].h > 135)) {
- code[i] = '1';
- } else if (bands[i].s < 78) {
- code[i] = '1';
- } else {
- code[i] = '0';
- }
- } else if (bands[i].v < 50) {
- if ((bands[i].h > 120) || (bands[i].h < 10)) {
- code[i] = '1';
- } else if (bands[i].h < 85) {
- code[i] = '5';
- } else {
- code[i] = '8';
- }
- } else if (bands[i].v < 70) {
- if (bands[i].h < 90) {
- code[i] = '3';
- } else {
- code[i] = '2';
- }
- } else if (bands[i].v < 100) {
- if (bands[i].h < 10) {
- code[i] = '3';
- } else if (bands[i].h < 40) {
- code[i] = 'g';
- } else if (bands[i].h < 85) {
- code[i] = '4';
- } else if (bands[i].h < 140) {
- code[i] = '6';
- } else {
- code[i] = '2';
- }
- } else {
- if (bands[i].h < 45) {
- code[i] = '3';
- } else if (bands[i].h < 105) {
- code[i] = '9';
- } else if (bands[i].h < 140) {
- code[i] = '7';
- } else {
- code[i] = '2';
- }
- }
- }
-
- /* Write bands' code into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Code: \"%s\"",
- code);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time6: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Calculate resistor value */
- {
- /* Measure time */
- time_0 = clock();
-
- /* Base value */
- base = (code[0] - '0') * 100 +
- (code[1] - '0') * 10 +
- (code[2] - '0');
-
- /* Calculate resistance */
- int power;
- if ((code[3] > '0') && (code[3] < '9')) {
- power = code[3] - '0';
- } else if (code[3] == 'g') {
- power = -1;
- } else if (code[3] == 's') {
- power = -2;
- }
- resistance = base * pow(10, power);
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time7: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Calculate resistor tolerance */
- {
- /* Measure time */
- time_0 = clock();
-
- switch (code[4]) {
- case '1':
- tolerance = 1;
- break;
- case '2':
- tolerance = 2;
- break;
- case '4':
- case 'g':
- case 'n':
- tolerance = 5;
- break;
- case '8':
- tolerance = 10;
- break;
- default:
- status = RESISTOR_NOK_TOLERANCE;
- result_resistor(status);
- return status;
- }
-
- /* Write resistance value into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Resistance: %.2E ± %i% Ohm",
- resistance, tolerance);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time8: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Check STD value */
- {
- /* Measure time */
- time_0 = clock();
-
- /* Check that base value is a standard value */
- int std_values_10 [12] = {10,12,15,18,22,27,33,39,47,56,68,82};
- int std_values_5 [12] = {11,13,16,20,24,30,36,43,51,62,75,91};
- bool std_value_nok;
- std_value_nok = true;
- for (i = 0; i < 12; i++) {
- if (base == std_values_10[i]) {
- std_value_nok = false;
- }
- if (base == (std_values_10[i] * 10)) {
- std_value_nok = false;
- }
- }
- if (tolerance <= 5) {
- for (i = 0; i < 12; i++) {
- if (base == std_values_5[i]) {
- std_value_nok = false;
- }
- if (base == (std_values_5[i] * 10)) {
- std_value_nok = false;
- }
- }
- }
- if (std_value_nok) {
- status = RESISTOR_NOK_STD_VALUE;
- result_resistor(status);
- return status;
- }
-
- /* Calculate resistance */
- int power;
- if ((code[3] > '0') && (code[3] < '9')) {
- power = code[3] - '0';
- } else if (code[3] == 'g') {
- power = -1;
- } else if (code[3] == 's') {
- power = -2;
- }
- resistance = base * pow(10, power);
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time7: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
-
- status = RESISTOR_OK;
- result_resistor(status);
- return status;
-}
-
-static void result_resistor (int status)
-{
- /* Cleanup */
-
- /* Write result into log */
- char result [LOG_LINE_LEN];
- switch (status) {
- case RESISTOR_OK:
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Resistor: OK");
- break;
- case RESISTOR_NOK_RESISTOR:
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Resistor: NOK_RESISTOR");
- break;
- case RESISTOR_NOK_BANDS:
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Resistor: NOK_BANDS");
- break;
- case RESISTOR_NOK_STD_VALUE:
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Resistor: NOK_STD_VALUE");
- break;
- case RESISTOR_NOK_TOLERANCE:
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Resistor: NOK_TOLERANCE");
- break;
- default:
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Resistor: NOK");
- break;
- }
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
-}
-
-static void proc_apply (void)
-{
- img_iface_act(IMG_IFACE_ACT_APPLY, NULL);
-}
-
-static void proc_save_mem (int n)
-{
- img_iface_act(IMG_IFACE_ACT_SAVE_MEM, (void *)&n);
-}
-
-static void proc_load_mem (int n)
-{
- img_iface_act(IMG_IFACE_ACT_LOAD_MEM, (void *)&n);
-
- proc_show_img();
-}
-
-static void proc_save_ref (void)
-{
- img_iface_act(IMG_IFACE_ACT_SAVE_REF, NULL);
-}
-
-static void proc_save_file (void)
-{
- img_iface_act(IMG_IFACE_ACT_SAVE_FILE, NULL);
-}
-
-static void proc_local_max (void)
-{
- img_iface_act(IMG_IFACE_ACT_LOCAL_MAX, NULL);
-
- proc_show_img();
-}
-
-static void proc_lines_vertical (void)
-{
- img_iface_act(IMG_IFACE_ACT_LINES_VERTICAL, NULL);
-
- proc_show_img();
-}
-
-static void proc_median_horizontal (void)
-{
- img_iface_act(IMG_IFACE_ACT_MEDIAN_HORIZONTAL, NULL);
-
- proc_show_img();
-}
-
-static void proc_median_vertical (void)
-{
- img_iface_act(IMG_IFACE_ACT_MEDIAN_VERTICAL, NULL);
-
- proc_show_img();
-}
-
-static void proc_pixel_value (int x, int y, unsigned char *val)
-{
- struct Img_Iface_Data_Pixel_Value data;
- data.x = x;
- data.y = y;
- data.val = val;
- img_iface_act(IMG_IFACE_ACT_PIXEL_VALUE, (void *)&data);
-}
-
-static void proc_ROI (int x, int y, int w, int h)
-{
- struct Img_Iface_Data_SetROI data;
- data.rect.x = x;
- data.rect.y = y;
- data.rect.width = w;
- data.rect.height = h;
- img_iface_act(IMG_IFACE_ACT_SET_ROI, (void *)&data);
-
- proc_show_img();
-}
-
-static void proc_and_2ref (void)
-{
- img_iface_act(USER_IFACE_ACT_AND_2REF, NULL);
-
- proc_show_img();
-}
-
-static void proc_not (void)
-{
- img_iface_act(USER_IFACE_ACT_NOT, NULL);
-
- proc_show_img();
-}
-
-static void proc_or_2ref (void)
-{
- img_iface_act(USER_IFACE_ACT_OR_2REF, NULL);
-
- proc_show_img();
-}
-
-static void proc_cmp (int cmp)
-{
- struct Img_Iface_Data_Component data;
- data.cmp = cmp;
- img_iface_act(IMG_IFACE_ACT_COMPONENT, (void *)&data);
-
- proc_show_img();
-}
-
-static void proc_dilate (int size)
-{
- struct Img_Iface_Data_Dilate_Erode data;
- data.i = size;
- img_iface_act(IMG_IFACE_ACT_DILATE, (void *)&data);
-
- proc_show_img();
-}
-
-static void proc_erode (int size)
-{
- struct Img_Iface_Data_Dilate_Erode data;
- data.i = size;
- img_iface_act(IMG_IFACE_ACT_ERODE, (void *)&data);
-
- proc_show_img();
-}
-
-static void proc_dilate_erode (int size)
-{
- struct Img_Iface_Data_Dilate_Erode data;
- data.i = size;
- img_iface_act(IMG_IFACE_ACT_DILATE_ERODE, (void *)&data);
-
- proc_show_img();
-}
-
-static void proc_erode_dilate (int size)
-{
- struct Img_Iface_Data_Dilate_Erode data;
- data.i = size;
- img_iface_act(IMG_IFACE_ACT_ERODE_DILATE, (void *)&data);
-
- proc_show_img();
-}
-
-static void proc_smooth (int method, int ksize)
-{
- struct Img_Iface_Data_Smooth data;
- data.method = method;
- data.ksize = ksize;
- img_iface_act(IMG_IFACE_ACT_SMOOTH, (void *)&data);
-
- proc_show_img();
-}
-
-static void proc_rotate (class cv::RotatedRect *rect)
-{
- struct Img_Iface_Data_Rotate data;
- data.center.x = rect->center.x;
- data.center.y = rect->center.y;
- data.angle = rect->angle;
- img_iface_act(IMG_IFACE_ACT_ROTATE, (void *)&data);
-
- proc_show_img();
-}
-
-static void proc_adaptive_threshold (int method, int type, int ksize)
-{
- struct Img_Iface_Data_Adaptive_Thr data;
- data.method = method;
- data.thr_typ = type;
- data.ksize = ksize;
- img_iface_act(USER_IFACE_ACT_ADAPTIVE_THRESHOLD, (void *)&data);
-
- proc_show_img();
-}
-
-static void proc_cvt_color (int method)
-{
- struct Img_Iface_Data_Cvt_Color data;
- data.method = method;
- img_iface_act(IMG_IFACE_ACT_CVT_COLOR, (void *)&data);
-
- proc_show_img();
-}
-
-static void proc_threshold (int type, int size)
-{
- struct Img_Iface_Data_Threshold data;
- data.thr_typ = type;
- data.thr_val = size;
- img_iface_act(IMG_IFACE_ACT_THRESHOLD, (void *)&data);
-
- proc_show_img();
-}
-
-static void proc_distance_transform (void)
-{
- img_iface_act(IMG_IFACE_ACT_DISTANCE_TRANSFORM, NULL);
-
- proc_show_img();
-}
-
-static void proc_contours (
- std::vector <std::vector <class cv::Point_ <int>>> *contours,
- class cv::Mat *hierarchy)
-{
- struct Img_Iface_Data_Contours data;
- data.contours = contours;
- data.hierarchy = hierarchy;
- img_iface_act(IMG_IFACE_ACT_CONTOURS, (void *)&data);
-
- proc_show_img();
-}
-
-static void proc_contours_size (
- std::vector <std::vector <class cv::Point_ <int>>> *contours,
- double *area,
- double *perimeter)
-{
- struct Img_Iface_Data_Contours_Size data;
- data.contours = contours;
- data.area = area;
- data.perimeter = perimeter;
- img_iface_act(IMG_IFACE_ACT_CONTOURS_SIZE, (void *)&data);
-}
-
-static void proc_bounding_rect (
- std::vector <class cv::Point_ <int>> *contour,
- class cv::Rect_ <int> *rect,
- bool show)
-{
- struct Img_Iface_Data_Bounding_Rect data;
- data.contour = contour;
- data.rect = rect;
- data.show = show;
- img_iface_act(IMG_IFACE_ACT_BOUNDING_RECT, (void *)&data);
-
- if (show) {
- proc_show_img();
- }
-}
-
-static void proc_fit_ellipse (
- std::vector <class cv::Point_ <int>> *contour,
- class cv::RotatedRect *rect,
- bool show)
-{
- struct Img_Iface_Data_MinARect data;
- data.contour = contour;
- data.rect = rect;
- data.show = show;
- img_iface_act(IMG_IFACE_ACT_FIT_ELLIPSE, (void *)&data);
-
-
- if (show) {
- proc_show_img();
- }
-}
-
-static void proc_min_area_rect (
- std::vector <class cv::Point_ <int>> *contour,
- class cv::RotatedRect *rect,
- bool show)
-{
- struct Img_Iface_Data_MinARect data;
- data.contour = contour;
- data.rect = rect;
- data.show = show;
- img_iface_act(IMG_IFACE_ACT_MIN_AREA_RECT, (void *)&data);
-
- if (show) {
- proc_show_img();
- }
-}
-
-static void proc_OCR (int lang, int conf)
-{
- struct Img_Iface_Data_Read data;
- data.lang = lang; /* eng=0, spa=1, cat=2 */
- data.conf = conf; /* none=0, price=1 */
- img_iface_act(IMG_IFACE_ACT_READ, (void *)&data);
-}
-
-static void proc_zbar (int type)
-{
- struct Img_Iface_Data_Decode data;
- data.code_type = (enum zbar::zbar_symbol_type_e)type;
- img_iface_act(IMG_IFACE_ACT_DECODE, (void *)&data);
-}
-
-static void proc_show_img (void)
-{
- if (proc_debug >= PROC_DBG_DELAY_STEP) {
- img_iface_show_img();
-
- if (proc_debug >= PROC_DBG_STOP_STEP) {
- getchar();
- }
- }
-}
-
-
-
-static int proc_resistor (void)
-{
- int status;
-
- double times;
- clock_t time_0;
- clock_t time_1;
-
- std::vector <std::vector <cv::Point_ <int>>> contours;
- class cv::Mat hierarchy;
- class cv::RotatedRect rect_rot;
- class cv::Rect_ <int> rect;
- int x;
- int y;
- int w;
- int h;
-
- int bkgd;
-
- struct {
- /* position */
- int x;
- int y;
-
- /* value */
- unsigned char h;
- unsigned char s;
- unsigned char v;
- } bands [5];
-
- char code [6] = {'\0', '\0', '\0', '\0', '\0', '\0'};
- int base;
- float resistance;
- int tolerance;
-
- int i;
- int j;
-
- proc_save_mem(0);
- /* Find resistor (position and angle) */
- {
- /* Measure time */
- time_0 = clock();
-
- /* BGR -> HSV */
- proc_cvt_color(cv::COLOR_BGR2HSV);
- proc_save_mem(19);
-
- proc_cmp(IMG_IFACE_CMP_SATURATION);
- proc_smooth(IMGI_SMOOTH_MEDIAN, 7);
- proc_threshold(cv::THRESH_BINARY, IMG_IFACE_THR_OTSU);
- proc_save_mem(1);
- proc_dilate_erode(10);
- proc_contours(&contours, &hierarchy);
-
- /* If no contour is found, error: NOK_RESISTOR */
- if (!contours.size()) {
- status = RESISTOR_NOK_RESISTOR;
- result_resistor(status);
- return status;
- }
-
- proc_min_area_rect(&(contours[0]), &rect_rot, true);
-
- /* If angle is < -45º, it is taking into acount the incorrect side */
- if (rect_rot.angle < -45.0) {
- rect_rot.angle += 90.0;
- }
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time0: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Align resistor, find its dimensions, and crop */
- {
- /* Measure time */
- time_0 = clock();
-
- /* Align */
- proc_load_mem(19);
- proc_rotate(&rect_rot);
- proc_save_mem(2);
- proc_load_mem(1);
- proc_rotate(&rect_rot);
- proc_save_mem(3);
-
- /* Dimensions */
- proc_contours(&contours, &hierarchy);
- proc_bounding_rect(&(contours[0]), &rect, true);
-
- /* Crop */
- proc_load_mem(2);
- w = rect.width;
- h = rect.height;
- x = rect.x;
- y = rect.y;
- proc_ROI(x, y, w, h);
- proc_save_mem(4);
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time1: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Find backgroung color */
- {
- /* Measure time */
- time_0 = clock();
-
- /* hue */
- uint8_t bkgd_hue;
- proc_cmp(IMG_IFACE_CMP_HUE);
- proc_median_vertical();
- proc_median_horizontal();
- proc_pixel_value(0, 0, &bkgd_hue);
-
- /* saturation */
- uint8_t bkgd_sat;
- proc_load_mem(4);
- proc_cmp(IMG_IFACE_CMP_SATURATION);
- proc_median_vertical();
- proc_median_horizontal();
- proc_pixel_value(0, 0, &bkgd_sat);
-
- if (bkgd_hue < 50) {
- /* Beige */
- bkgd = 0;
- } else {
- /* Blue */
- if ((bkgd_hue <= 90) || (bkgd_sat <= 140)) {
- /* Teal blue */
- bkgd = 1;
- } else if (bkgd_hue >= 105) {
- /* Dark blue */
- bkgd = 2;
- } else {
- /* Normal blue */
- bkgd = 3;
- }
- }
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time2: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Crop more */
- {
- /* Measure time */
- time_0 = clock();
-
- /* Dimensions */
- proc_load_mem(3);
- proc_dilate_erode(10);
- proc_erode_dilate(rect.height / 1.9 - 9);
- proc_contours(&contours, &hierarchy);
- proc_bounding_rect(&(contours[0]), &rect, true);
-
- /* Crop */
- proc_load_mem(2);
- w = rect.width * 0.9;
- h = rect.height * 0.9;
- x = rect.x + w * (1.0 - 0.9) / 2.0;
- y = rect.y + h * (1.0 - 0.9) / 2.0;
- proc_ROI(x, y, w, h);
- proc_save_mem(4);
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time1: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Separate background (BK) and lines (WH) */
- {
- /* Measure time */
- time_0 = clock();
-
- /* hue */
- proc_load_mem(4);
- proc_cmp(IMG_IFACE_CMP_HUE);
- proc_median_vertical();
- proc_save_mem(9);
- switch (bkgd) {
- case 0:
- proc_threshold(cv::THRESH_TOZERO_INV, 20);
- proc_threshold(cv::THRESH_TOZERO, 5);
- break;
- case 1:
- proc_threshold(cv::THRESH_TOZERO_INV, 100);
- proc_threshold(cv::THRESH_TOZERO, 70);
- break;
- case 2:
- proc_threshold(cv::THRESH_TOZERO_INV, 115);
- proc_threshold(cv::THRESH_TOZERO, 100);
- break;
- case 3:
- proc_threshold(cv::THRESH_TOZERO_INV, 110);
- proc_threshold(cv::THRESH_TOZERO, 90);
- break;
- }
- proc_threshold(cv::THRESH_BINARY_INV, 1);
- proc_save_mem(5);
-
-#if 0
- /* saturation */
- proc_load_mem(4);
- proc_cmp(IMG_IFACE_CMP_SATURATION);
- proc_median_vertical();
- proc_save_mem(10);
- switch (bkgd) {
- case 0:
- proc_threshold(cv::THRESH_TOZERO, 100);
- break;
- case 1:
- proc_threshold(cv::THRESH_TOZERO, 95);
- break;
- case 2:
- proc_threshold(cv::THRESH_TOZERO, 200);
- break;
- case 3:
- proc_threshold(cv::THRESH_TOZERO, 130);
- break;
- }
- proc_threshold(cv::THRESH_BINARY_INV, 1);
- proc_save_mem(6);
-
- /* value */
- proc_load_mem(4);
- proc_cmp(IMG_IFACE_CMP_VALUE);
- proc_median_vertical();
- proc_save_mem(11);
- switch (bkgd) {
- case 0:
- proc_threshold(cv::THRESH_TOZERO_INV, 130);
- proc_threshold(cv::THRESH_TOZERO, 65);
- break;
- case 1:
- proc_threshold(cv::THRESH_TOZERO_INV, 155);
- proc_threshold(cv::THRESH_TOZERO, 60);
- break;
- case 2:
- proc_threshold(cv::THRESH_TOZERO_INV, 140);
- proc_threshold(cv::THRESH_TOZERO, 60);
- break;
- case 3:
- proc_threshold(cv::THRESH_TOZERO_INV, 165);
- proc_threshold(cv::THRESH_TOZERO, 45);
- break;
- }
- proc_threshold(cv::THRESH_BINARY_INV, 1);
- proc_save_mem(7);
-
- /* Merge the components: H | S | V */
- proc_save_ref();
- proc_load_mem(5);
- proc_or_2ref();
- proc_save_ref();
- proc_load_mem(6);
- proc_or_2ref();
- proc_dilate_erode(1);
- proc_save_mem(8);
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time3: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Find bands: contours -> rectangles -> ROIs */
- {
- /* Measure time */
- time_0 = clock();
-
- /* Contours */
- proc_contours(&contours, &hierarchy);
-
- bool bands_nok;
- bands_nok = (contours.size() < 3) ||
- (contours.size() > 5);
- if (bands_nok) {
- status = RESISTOR_NOK_BANDS;
- result_resistor(status);
- return status;
- }
-
- /* Band 0 */
- if (contours.size() == 5) {
- proc_bounding_rect(&(contours[4]), &rect, true);
- bands[0].x = rect.x + rect.width / 2.0;
- bands[0].y = rect.y + rect.height / 2.0;
- }
- /* Band 1 */
- if (contours.size() > 3) {
- proc_bounding_rect(&(contours[3]), &rect, true);
- } else {
- proc_bounding_rect(&(contours[2]), &rect, true);
- }
- bands[1].x = rect.x + rect.width / 2.0;
- bands[1].y = rect.y + rect.height / 2.0;
- /* Band 2 */
- if (contours.size() > 3) {
- proc_bounding_rect(&(contours[2]), &rect, true);
- } else {
- proc_bounding_rect(&(contours[1]), &rect, true);
- }
- bands[2].x = rect.x + rect.width / 2.0;
- bands[2].y = rect.y + rect.height / 2.0;
- /* Band 3 */
- if (contours.size() > 3) {
- proc_bounding_rect(&(contours[1]), &rect, true);
- } else {
- proc_bounding_rect(&(contours[0]), &rect, true);
- }
- bands[3].x = rect.x + rect.width / 2.0;
- bands[3].y = rect.y + rect.height / 2.0;
- /* Band 4 */
- if (contours.size() > 3) {
- proc_bounding_rect(&(contours[0]), &rect, true);
- bands[4].x = rect.x + rect.width / 2.0;
- bands[4].y = rect.y + rect.height / 2.0;
- }
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time4: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Read values on the center of each band */
- {
- /* Measure time */
- time_0 = clock();
-
- /* Hue */
- proc_load_mem(9);
- if (contours.size() == 5) {
- proc_pixel_value(bands[0].x, bands[0].y, &(bands[0].h));
- }
- proc_pixel_value(bands[1].x, bands[1].y, &(bands[1].h));
- proc_pixel_value(bands[2].x, bands[2].y, &(bands[2].h));
- proc_pixel_value(bands[3].x, bands[3].y, &(bands[3].h));
- if (contours.size() > 3) {
- proc_pixel_value(bands[4].x, bands[4].y, &(bands[4].h));
- }
-
- /* Saturation */
- proc_load_mem(10);
- if (contours.size() == 5) {
- proc_pixel_value(bands[0].x, bands[0].y, &(bands[0].s));
- }
- proc_pixel_value(bands[1].x, bands[1].y, &(bands[1].s));
- proc_pixel_value(bands[2].x, bands[2].y, &(bands[2].s));
- proc_pixel_value(bands[3].x, bands[3].y, &(bands[3].s));
- if (contours.size() > 3) {
- proc_pixel_value(bands[4].x, bands[4].y, &(bands[4].s));
- }
-
- /* Value */
- proc_load_mem(11);
- if (contours.size() == 5) {
- proc_pixel_value(bands[0].x, bands[0].y, &(bands[0].v));
- }
- proc_pixel_value(bands[1].x, bands[1].y, &(bands[1].v));
- proc_pixel_value(bands[2].x, bands[2].y, &(bands[2].v));
- proc_pixel_value(bands[3].x, bands[3].y, &(bands[3].v));
- if (contours.size() > 3) {
- proc_pixel_value(bands[4].x, bands[4].y, &(bands[4].v));
- }
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time5: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
-
- }
- /* Interpret colors */
- {
- /* Measure time */
- time_0 = clock();
-
- if (contours.size() == 5) {
- i = 0;
- } else {
- code[0] = '0';
- i = 1;
- }
- int loop_lim;
- if (contours.size() > 3) {
- loop_lim = 5;
- } else {
- code[4] = 'n';
- loop_lim = 4;
- }
- for (; i < loop_lim; i++) {
- if (bands[i].v < 24) {
- code[i] = '0';
- } else if (bands[i].v < 28) {
- if ((bands[i].h < 90) || (bands[i].h > 135)) {
- code[i] = '1';
- } else if (bands[i].s < 78) {
- code[i] = '1';
- } else {
- code[i] = '0';
- }
- } else if (bands[i].v < 50) {
- if ((bands[i].h > 120) || (bands[i].h < 10)) {
- code[i] = '1';
- } else if (bands[i].h < 85) {
- code[i] = '5';
- } else {
- code[i] = '8';
- }
- } else if (bands[i].v < 70) {
- if (bands[i].h < 90) {
- code[i] = '3';
- } else {
- code[i] = '2';
- }
- } else if (bands[i].v < 100) {
- if (bands[i].h < 10) {
- code[i] = '3';
- } else if (bands[i].h < 40) {
- code[i] = 'g';
- } else if (bands[i].h < 85) {
- code[i] = '4';
- } else if (bands[i].h < 140) {
- code[i] = '6';
- } else {
- code[i] = '2';
- }
- } else {
- if (bands[i].h < 45) {
- code[i] = '3';
- } else if (bands[i].h < 105) {
- code[i] = '9';
- } else if (bands[i].h < 140) {
- code[i] = '7';
- } else {
- code[i] = '2';
- }
- }
- }
-
- /* Write bands' code into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Code: \"%s\"",
- code);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time6: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Calculate resistor value */
- {
- /* Measure time */
- time_0 = clock();
-
- /* Base value */
- base = (code[0] - '0') * 100 +
- (code[1] - '0') * 10 +
- (code[2] - '0');
-
- /* Calculate resistance */
- int power;
- if ((code[3] > '0') && (code[3] < '9')) {
- power = code[3] - '0';
- } else if (code[3] == 'g') {
- power = -1;
- } else if (code[3] == 's') {
- power = -2;
- }
- resistance = base * pow(10, power);
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time7: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Calculate resistor tolerance */
- {
- /* Measure time */
- time_0 = clock();
-
- switch (code[4]) {
- case '1':
- tolerance = 1;
- break;
- case '2':
- tolerance = 2;
- break;
- case '4':
- case 'g':
- case 'n':
- tolerance = 5;
- break;
- case '8':
- tolerance = 10;
- break;
- default:
- status = RESISTOR_NOK_TOLERANCE;
- result_resistor(status);
- return status;
- }
-
- /* Write resistance value into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Resistance: %.2E ± %i% Ohm",
- resistance, tolerance);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time8: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
- }
- /* Check STD value */
- {
- /* Measure time */
- time_0 = clock();
-
- /* Check that base value is a standard value */
- int std_values_10 [12] = {10,12,15,18,22,27,33,39,47,56,68,82};
- int std_values_5 [12] = {11,13,16,20,24,30,36,43,51,62,75,91};
- bool std_value_nok;
- std_value_nok = true;
- for (i = 0; i < 12; i++) {
- if (base == std_values_10[i]) {
- std_value_nok = false;
- }
- if (base == (std_values_10[i] * 10)) {
- std_value_nok = false;
- }
- }
- if (tolerance <= 5) {
- for (i = 0; i < 12; i++) {
- if (base == std_values_5[i]) {
- std_value_nok = false;
- }
- if (base == (std_values_5[i] * 10)) {
- std_value_nok = false;
- }
- }
- }
- if (std_value_nok) {
- status = RESISTOR_NOK_STD_VALUE;
- result_resistor(status);
- return status;
- }
-
- /* Calculate resistance */
- int power;
- if ((code[3] > '0') && (code[3] < '9')) {
- power = code[3] - '0';
- } else if (code[3] == 'g') {
- power = -1;
- } else if (code[3] == 's') {
- power = -2;
- }
- resistance = base * pow(10, power);
-
- /* Measure time */
- time_1 = clock();
- times = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
- /* Write time into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Time7: %.3lf", times);
- user_iface_log.lvl[user_iface_log.len] = 0;
- (user_iface_log.len)++;
-#endif
- }
-
- proc_apply();
- proc_save_file();
-
- status = -1;
- result_resistor(status);
- return status;
-}
-
-
-/******************************************************************************
- ******* end of file **********************************************************
- ******************************************************************************/
diff --git a/modules/proc/src/proc_coins.cpp b/modules/proc/src/proc_coins.cpp
new file mode 100644
index 0000000..676e214
--- /dev/null
+++ b/modules/proc/src/proc_coins.cpp
@@ -0,0 +1,137 @@
+/******************************************************************************
+ * Copyright (C) 2018 Alejandro Colomar Andrés *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* headers **************************************************************
+ ******************************************************************************/
+/* Standard C ----------------------------------------------------------------*/
+ /* snprintf() & fflush() */
+ #include <cstdio>
+
+/* Packages ------------------------------------------------------------------*/
+ /* openCV */
+ #include <opencv2/opencv.hpp>
+
+/* Project -------------------------------------------------------------------*/
+ /* constants */
+ #include "img_iface.hpp"
+ /* user_iface_log */
+ #include "user_iface.hpp"
+
+/* Module --------------------------------------------------------------------*/
+ #include "proc_common.hpp"
+
+ #include "proc_coins.hpp"
+
+
+/******************************************************************************
+ ******* variables ************************************************************
+ ******************************************************************************/
+/* Global --------------------------------------------------------------------*/
+
+/* Static --------------------------------------------------------------------*/
+static std::vector <std::vector <cv::Point_ <int>>> contours;
+static class cv::Mat hierarchy;
+
+
+/******************************************************************************
+ ******* static functions *****************************************************
+ ******************************************************************************/
+static void result_coins (int status);
+
+static int coins_find (void);
+
+
+/******************************************************************************
+ ******* global functions *****************************************************
+ ******************************************************************************/
+int proc_coins (void)
+{
+ int status;
+
+ proc_save_mem(0);
+ /* Find coins */
+ {
+ /* Measure time */
+ clock_start();
+
+ status = coins_find();
+ if (status) {
+ result_coins(status);
+ return status;
+ }
+
+ /* Measure time */
+ clock_stop("Find coins");
+ }
+
+ status = COINS_OK;
+ result_coins(status);
+ return status;
+}
+
+
+/******************************************************************************
+ ******* static functions *****************************************************
+ ******************************************************************************/
+static void result_coins (int status)
+{
+ /* Cleanup */
+
+ /* Write result into log */
+ char result [LOG_LINE_LEN];
+ switch (status) {
+ case COINS_OK:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Coin: OK");
+ break;
+ case COINS_NOK_COINS:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Coin: NOK_COINS");
+ break;
+ case COINS_NOK_OVERLAP:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Coin: NOK_OVERLAP");
+ break;
+ default:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Coin: NOK");
+ break;
+ }
+ user_iface_log.lvl[user_iface_log.len] = 0;
+ (user_iface_log.len)++;
+}
+
+static int coins_find (void)
+{
+ int status;
+
+ proc_load_mem(0);
+
+ proc_cmp(IMG_IFACE_CMP_BLUE);
+// proc_smooth(IMGI_SMOOTH_MEDIAN, 11);
+ proc_threshold(cv::THRESH_BINARY_INV, IMG_IFACE_THR_OTSU);
+// proc_threshold(cv::THRESH_BINARY_INV, 100);
+ proc_distance_transform();
+ proc_local_max();
+ proc_dilate(8);
+ proc_save_mem(1);
+
+ proc_contours(&contours, &hierarchy);
+
+ /* If no contour is found, error: NOK_COINS */
+ if (!contours.size()) {
+ status = COINS_NOK_COINS;
+ return status;
+ }
+
+ status = COINS_OK;
+ return status;
+}
+
+
+/******************************************************************************
+ ******* end of file **********************************************************
+ ******************************************************************************/
diff --git a/modules/proc/src/proc_common.cpp b/modules/proc/src/proc_common.cpp
new file mode 100644
index 0000000..662e7f8
--- /dev/null
+++ b/modules/proc/src/proc_common.cpp
@@ -0,0 +1,376 @@
+/******************************************************************************
+ * Copyright (C) 2018 Alejandro Colomar Andrés *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* headers **************************************************************
+ ******************************************************************************/
+/* Standard C ----------------------------------------------------------------*/
+ /* snprintf() & fflush() */
+ #include <cstdio>
+ /* clock_t & clock() & CLOCKS_PER_SEC */
+ #include <ctime>
+
+/* Packages ------------------------------------------------------------------*/
+ /* openCV */
+ #include <opencv2/opencv.hpp>
+ /* enum zbar::zbar_symbol_type_e */
+ #include <zbar.h>
+
+/* Project -------------------------------------------------------------------*/
+ /* img_iface_act() */
+ #include "img_iface.hpp"
+ /* user_iface_log */
+ #include "user_iface.hpp"
+
+/* Module --------------------------------------------------------------------*/
+ /* enum Proc_DBG */
+ #include "proc_iface.hpp"
+
+ #include "proc_common.hpp"
+
+
+/******************************************************************************
+ ******* variables ************************************************************
+ ******************************************************************************/
+/* Global --------------------------------------------------------------------*/
+
+/* Static --------------------------------------------------------------------*/
+static clock_t clock_0;
+static clock_t clock_1;
+
+
+/******************************************************************************
+ ******* static functions *****************************************************
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* global functions *****************************************************
+ ******************************************************************************/
+void proc_apply (void)
+{
+ img_iface_act(IMG_IFACE_ACT_APPLY, NULL);
+}
+
+void proc_save_mem (int n)
+{
+ img_iface_act(IMG_IFACE_ACT_SAVE_MEM, (void *)&n);
+}
+
+void proc_load_mem (int n)
+{
+ img_iface_act(IMG_IFACE_ACT_LOAD_MEM, (void *)&n);
+
+ proc_show_img();
+}
+
+void proc_save_ref (void)
+{
+ img_iface_act(IMG_IFACE_ACT_SAVE_REF, NULL);
+}
+
+void proc_save_file (void)
+{
+ img_iface_act(IMG_IFACE_ACT_SAVE_FILE, NULL);
+}
+
+void proc_local_max (void)
+{
+ img_iface_act(IMG_IFACE_ACT_LOCAL_MAX, NULL);
+
+ proc_show_img();
+}
+
+void proc_lines_vertical (void)
+{
+ img_iface_act(IMG_IFACE_ACT_LINES_VERTICAL, NULL);
+
+ proc_show_img();
+}
+
+void proc_median_horizontal (void)
+{
+ img_iface_act(IMG_IFACE_ACT_MEDIAN_HORIZONTAL, NULL);
+
+ proc_show_img();
+}
+
+void proc_median_vertical (void)
+{
+ img_iface_act(IMG_IFACE_ACT_MEDIAN_VERTICAL, NULL);
+
+ proc_show_img();
+}
+
+void proc_pixel_value (int x, int y, unsigned char *val)
+{
+ struct Img_Iface_Data_Pixel_Value data;
+ data.x = x;
+ data.y = y;
+ data.val = val;
+ img_iface_act(IMG_IFACE_ACT_PIXEL_VALUE, (void *)&data);
+}
+
+void proc_ROI (int x, int y, int w, int h)
+{
+ struct Img_Iface_Data_SetROI data;
+ data.rect.x = x;
+ data.rect.y = y;
+ data.rect.width = w;
+ data.rect.height = h;
+ img_iface_act(IMG_IFACE_ACT_SET_ROI, (void *)&data);
+
+ proc_show_img();
+}
+
+void proc_and_2ref (void)
+{
+ img_iface_act(USER_IFACE_ACT_AND_2REF, NULL);
+
+ proc_show_img();
+}
+
+void proc_not (void)
+{
+ img_iface_act(USER_IFACE_ACT_NOT, NULL);
+
+ proc_show_img();
+}
+
+void proc_or_2ref (void)
+{
+ img_iface_act(USER_IFACE_ACT_OR_2REF, NULL);
+
+ proc_show_img();
+}
+
+void proc_cmp (int cmp)
+{
+ struct Img_Iface_Data_Component data;
+ data.cmp = cmp;
+ img_iface_act(IMG_IFACE_ACT_COMPONENT, (void *)&data);
+
+ proc_show_img();
+}
+
+void proc_dilate (int size)
+{
+ struct Img_Iface_Data_Dilate_Erode data;
+ data.i = size;
+ img_iface_act(IMG_IFACE_ACT_DILATE, (void *)&data);
+
+ proc_show_img();
+}
+
+void proc_erode (int size)
+{
+ struct Img_Iface_Data_Dilate_Erode data;
+ data.i = size;
+ img_iface_act(IMG_IFACE_ACT_ERODE, (void *)&data);
+
+ proc_show_img();
+}
+
+void proc_dilate_erode (int size)
+{
+ struct Img_Iface_Data_Dilate_Erode data;
+ data.i = size;
+ img_iface_act(IMG_IFACE_ACT_DILATE_ERODE, (void *)&data);
+
+ proc_show_img();
+}
+
+void proc_erode_dilate (int size)
+{
+ struct Img_Iface_Data_Dilate_Erode data;
+ data.i = size;
+ img_iface_act(IMG_IFACE_ACT_ERODE_DILATE, (void *)&data);
+
+ proc_show_img();
+}
+
+void proc_smooth (int method, int ksize)
+{
+ struct Img_Iface_Data_Smooth data;
+ data.method = method;
+ data.ksize = ksize;
+ img_iface_act(IMG_IFACE_ACT_SMOOTH, (void *)&data);
+
+ proc_show_img();
+}
+
+void proc_rotate (class cv::RotatedRect *rect)
+{
+ struct Img_Iface_Data_Rotate data;
+ data.center.x = rect->center.x;
+ data.center.y = rect->center.y;
+ data.angle = rect->angle;
+ img_iface_act(IMG_IFACE_ACT_ROTATE, (void *)&data);
+
+ proc_show_img();
+}
+
+void proc_adaptive_threshold (int method, int type, int ksize)
+{
+ struct Img_Iface_Data_Adaptive_Thr data;
+ data.method = method;
+ data.thr_typ = type;
+ data.ksize = ksize;
+ img_iface_act(USER_IFACE_ACT_ADAPTIVE_THRESHOLD, (void *)&data);
+
+ proc_show_img();
+}
+
+void proc_cvt_color (int method)
+{
+ struct Img_Iface_Data_Cvt_Color data;
+ data.method = method;
+ img_iface_act(IMG_IFACE_ACT_CVT_COLOR, (void *)&data);
+
+ proc_show_img();
+}
+
+void proc_threshold (int type, int size)
+{
+ struct Img_Iface_Data_Threshold data;
+ data.thr_typ = type;
+ data.thr_val = size;
+ img_iface_act(IMG_IFACE_ACT_THRESHOLD, (void *)&data);
+
+ proc_show_img();
+}
+
+void proc_distance_transform (void)
+{
+ img_iface_act(IMG_IFACE_ACT_DISTANCE_TRANSFORM, NULL);
+
+ proc_show_img();
+}
+
+void proc_contours (
+ std::vector <std::vector <class cv::Point_ <int>>> *contours,
+ class cv::Mat *hierarchy)
+{
+ struct Img_Iface_Data_Contours data;
+ data.contours = contours;
+ data.hierarchy = hierarchy;
+ img_iface_act(IMG_IFACE_ACT_CONTOURS, (void *)&data);
+
+ proc_show_img();
+}
+
+void proc_contours_size (
+ std::vector <std::vector <class cv::Point_ <int>>> *contours,
+ double *area,
+ double *perimeter)
+{
+ struct Img_Iface_Data_Contours_Size data;
+ data.contours = contours;
+ data.area = area;
+ data.perimeter = perimeter;
+ img_iface_act(IMG_IFACE_ACT_CONTOURS_SIZE, (void *)&data);
+}
+
+void proc_bounding_rect (
+ std::vector <class cv::Point_ <int>> *contour,
+ class cv::Rect_ <int> *rect,
+ bool show)
+{
+ struct Img_Iface_Data_Bounding_Rect data;
+ data.contour = contour;
+ data.rect = rect;
+ data.show = show;
+ img_iface_act(IMG_IFACE_ACT_BOUNDING_RECT, (void *)&data);
+
+ if (show) {
+ proc_show_img();
+ }
+}
+
+void proc_fit_ellipse (
+ std::vector <class cv::Point_ <int>> *contour,
+ class cv::RotatedRect *rect,
+ bool show)
+{
+ struct Img_Iface_Data_MinARect data;
+ data.contour = contour;
+ data.rect = rect;
+ data.show = show;
+ img_iface_act(IMG_IFACE_ACT_FIT_ELLIPSE, (void *)&data);
+
+
+ if (show) {
+ proc_show_img();
+ }
+}
+
+void proc_min_area_rect (
+ std::vector <class cv::Point_ <int>> *contour,
+ class cv::RotatedRect *rect,
+ bool show)
+{
+ struct Img_Iface_Data_MinARect data;
+ data.contour = contour;
+ data.rect = rect;
+ data.show = show;
+ img_iface_act(IMG_IFACE_ACT_MIN_AREA_RECT, (void *)&data);
+
+ if (show) {
+ proc_show_img();
+ }
+}
+
+void proc_OCR (int lang, int conf)
+{
+ struct Img_Iface_Data_Read data;
+ data.lang = lang; /* eng=0, spa=1, cat=2 */
+ data.conf = conf; /* none=0, price=1 */
+ img_iface_act(IMG_IFACE_ACT_READ, (void *)&data);
+}
+
+void proc_zbar (int type)
+{
+ struct Img_Iface_Data_Decode data;
+ data.code_type = (enum zbar::zbar_symbol_type_e)type;
+ img_iface_act(IMG_IFACE_ACT_DECODE, (void *)&data);
+}
+
+void proc_show_img (void)
+{
+ if (proc_debug >= PROC_DBG_DELAY_STEP) {
+ img_iface_show_img();
+
+ if (proc_debug >= PROC_DBG_STOP_STEP) {
+ getchar();
+ }
+ }
+}
+
+void clock_start (void)
+{
+ clock_0 = clock();
+}
+
+void clock_stop (const char *txt)
+{
+ clock_t clock_diff;
+ double time_diff;
+
+ clock_1 = clock();
+ clock_diff = clock_1 - clock_0;
+ time_diff = (double)clock_diff / (double)CLOCKS_PER_SEC;
+
+ /* Write time_diff into log */
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "%s: Time: %.3lf",
+ txt, time_diff);
+ user_iface_log.lvl[user_iface_log.len] = 0;
+ (user_iface_log.len)++;
+}
+
+
+/******************************************************************************
+ ******* end of file **********************************************************
+ ******************************************************************************/
diff --git a/modules/proc/src/proc_iface.c b/modules/proc/src/proc_iface.c
new file mode 100644
index 0000000..d6108a5
--- /dev/null
+++ b/modules/proc/src/proc_iface.c
@@ -0,0 +1,185 @@
+/******************************************************************************
+ * Copyright (C) 2018 Alejandro Colomar Andrés *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* headers **************************************************************
+ ******************************************************************************/
+/* Standard C ----------------------------------------------------------------*/
+ /* errno */
+ #include <errno.h>
+ /* snprintf() & fflush() */
+ #include <stdio.h>
+ /* clock_t & clock() & CLOCKS_PER_SEC */
+ #include <time.h>
+
+/* libalx -------------------------------------------------------------------*/
+ /* alx_sscan_fname() */
+ #include "alx_input.h"
+
+/* Project -------------------------------------------------------------------*/
+ /* img_iface_load() */
+ #include "img_iface.h"
+ /* user_iface_log */
+ #include "user_iface.h"
+ /* saved_path */
+ #include "save.h"
+
+/* Module --------------------------------------------------------------------*/
+ #include "proc_label.h"
+ #include "proc_coins.h"
+ #include "proc_resistor.h"
+ #include "proc_common.h"
+
+ #include "proc_iface.h"
+
+
+/******************************************************************************
+ ******* variables ************************************************************
+ ******************************************************************************/
+/* Global --------------------------------------------------------------------*/
+ int proc_debug;
+ int proc_mode;
+
+/* Static --------------------------------------------------------------------*/
+static char proc_path [FILENAME_MAX];
+static char proc_fail_path [FILENAME_MAX];
+
+
+/******************************************************************************
+ ******* static functions *****************************************************
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* global functions *****************************************************
+ ******************************************************************************/
+int proc_iface_single (int action)
+{
+ int error;
+ clock_t time_0;
+ clock_t time_1;
+ double time_tot;
+
+ /* Init timer */
+ time_0 = clock();
+
+ /* Process */
+ switch (action) {
+ case PROC_MODE_LABEL:
+ error = proc_label();
+ break;
+ case PROC_MODE_COINS:
+ error = proc_coins();
+ break;
+ case PROC_MODE_RESISTOR:
+ error = proc_resistor();
+ break;
+ }
+
+ /* End timer */
+ time_1 = clock();
+
+ /* Calculate time in seconds */
+ time_tot = ((double) time_1 - time_0) / CLOCKS_PER_SEC;
+
+ /* Write time into log */
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Item total time: %.3lf",
+ time_tot);
+ user_iface_log.lvl[user_iface_log.len] = 0;
+ (user_iface_log.len)++;
+
+ return error;
+}
+
+void proc_iface_series (void)
+{
+ bool file_error;
+ int num_len;
+ char file_basename [FILENAME_MAX];
+ char file_ext [80];
+ char file_name [FILENAME_MAX];
+ bool proc_error;
+ char save_error_as [FILENAME_MAX];
+
+ switch (proc_mode) {
+ case PROC_MODE_LABEL:
+ snprintf(proc_path, FILENAME_MAX, "%s", labels_path);
+ snprintf(proc_fail_path, FILENAME_MAX, "%s", labels_fail_path);
+ snprintf(file_basename, 80, "b");
+ num_len = 4;
+ snprintf(file_ext, 80, ".BMP");
+ break;
+ case PROC_MODE_COINS:
+ snprintf(proc_path, FILENAME_MAX, "%s", coins_path);
+ snprintf(proc_fail_path, FILENAME_MAX, "%s", coins_fail_path);
+ snprintf(file_basename, 80, "c");
+ num_len = 4;
+ snprintf(file_ext, 80, ".png");
+ break;
+ case PROC_MODE_RESISTOR:
+ snprintf(proc_path, FILENAME_MAX, "%s", resistors_path);
+ snprintf(proc_fail_path, FILENAME_MAX, "%s", resistors_fail_path);
+ snprintf(file_basename, 80, "r");
+ num_len = 4;
+ snprintf(file_ext, 80, ".png");
+ break;
+ }
+
+ bool wh;
+ int i;
+ wh = true;
+ for (i = 0; wh; i++) {
+ snprintf(file_name, FILENAME_MAX, "%s%04i%s",
+ file_basename, i, file_ext);
+
+ file_error = alx_sscan_fname(proc_path, file_name,
+ true, file_name);
+
+ if (file_error) {
+ wh = false;
+ } else {
+ errno = 0;
+ img_iface_load(proc_path, file_name);
+
+ if (!errno) {
+ /* Process */
+ proc_error = proc_iface_single(proc_mode);
+
+ if (proc_error) {
+ /* Save failed image into file */
+ proc_show_img();
+ snprintf(save_error_as, FILENAME_MAX,
+ "%s%04i_err%s",
+ file_basename, i,
+ file_ext);
+ save_image_file(proc_fail_path,
+ save_error_as);
+ }
+
+ /* Show log */
+ char txt_tmp [80];
+ snprintf(txt_tmp, 80, "%04i", i);
+ user_iface_show_log(txt_tmp, "Item");
+
+ if (proc_debug >= PROC_DBG_STOP_ITEM) {
+ getchar();
+ }
+ } else {
+ printf("errno:%i\n", errno);
+ }
+ }
+ }
+}
+
+
+/******************************************************************************
+ ******* static functions *****************************************************
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* end of file **********************************************************
+ ******************************************************************************/
diff --git a/modules/proc/src/proc_label.cpp b/modules/proc/src/proc_label.cpp
new file mode 100644
index 0000000..765856d
--- /dev/null
+++ b/modules/proc/src/proc_label.cpp
@@ -0,0 +1,386 @@
+/******************************************************************************
+ * Copyright (C) 2018 Alejandro Colomar Andrés *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* headers **************************************************************
+ ******************************************************************************/
+/* Standard C ----------------------------------------------------------------*/
+ /* snprintf() */
+ #include <cstdio>
+ /* strcmp() */
+ #include <cstring>
+
+/* Packages ------------------------------------------------------------------*/
+ /* openCV */
+ #include <opencv2/opencv.hpp>
+ /* zbar::ZBAR_EAN13 */
+ #include <zbar.h>
+
+/* Project -------------------------------------------------------------------*/
+ /* zb_codes */
+ #include "img_iface.hpp"
+ /* user_iface_log */
+ #include "user_iface.hpp"
+
+/* Module --------------------------------------------------------------------*/
+ #include "proc_common.hpp"
+
+ #include "proc_label.hpp"
+
+
+/******************************************************************************
+ ******* variables ************************************************************
+ ******************************************************************************/
+/* Global --------------------------------------------------------------------*/
+
+/* Static --------------------------------------------------------------------*/
+static std::vector <std::vector <cv::Point_ <int>>> contours;
+static class cv::Mat hierarchy;
+static class cv::RotatedRect rect;
+
+
+/******************************************************************************
+ ******* static functions *****************************************************
+ ******************************************************************************/
+static void result_label (int status);
+
+static int label_find (void);
+static void label_align (void);
+static int find_cerdo (void);
+static int barcode_read (void);
+static int barcode_chk_prod (void);
+static void price_read (void);
+static int price_chk (void);
+
+
+/******************************************************************************
+ ******* global functions *****************************************************
+ ******************************************************************************/
+int proc_label (void)
+{
+ int status;
+
+ proc_save_mem(0);
+ /* Find label (position and angle) */
+ {
+ /* Measure time */
+ clock_start();
+
+ status = label_find();
+ if (status) {
+ result_label(status);
+ return status;
+ }
+
+ /* Measure time */
+ clock_stop("Find label");
+ }
+ /* Align label and extract green component */
+ {
+ /* Measure time */
+ clock_start();
+
+ label_align();
+
+ /* Measure time */
+ clock_stop("Align label");
+ }
+ /* Find "Cerdo" in aligned image */
+ {
+ /* Measure time */
+ clock_start();
+
+ status = find_cerdo();
+ if (status) {
+ result_label(status);
+ return status;
+ }
+
+ /* Measure time */
+ clock_stop("Find cerdo (OCR)");
+ }
+ /* Read barcode in original image */
+ {
+ /* Measure time */
+ clock_start();
+
+ status = barcode_read();
+ if (status) {
+ result_label(status);
+ return status;
+ }
+
+ /* Measure time */
+ clock_stop("Read barcode (zbar)");
+ }
+ /* Check product code in barcode */
+ {
+ /* Measure time */
+ clock_start();
+
+ status = barcode_chk_prod();
+ if (status) {
+ result_label(status);
+ return status;
+ }
+
+ /* Measure time */
+ clock_stop("Chk product code");
+ }
+ /* Read price in aligned image (green component) */
+ {
+ /* Measure time */
+ clock_start();
+
+ price_read();
+
+ /* Measure time */
+ clock_stop("Read price (OCR)");
+ }
+ /* Check label price with barcode price */
+ {
+ /* Measure time */
+ clock_start();
+
+ status = price_chk();
+ if (status) {
+ result_label(status);
+ return status;
+ }
+
+ /* Measure time */
+ clock_stop("Check price");
+ }
+
+ status = LABEL_OK;
+ result_label(status);
+ return status;
+}
+
+
+/******************************************************************************
+ ******* static functions *****************************************************
+ ******************************************************************************/
+static void result_label (int status)
+{
+ /* Cleanup */
+
+ /* Write result into log */
+ char result [LOG_LINE_LEN];
+ switch (status) {
+ case LABEL_OK:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Label: OK");
+ break;
+ case LABEL_NOK_LABEL:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Label: NOK_LABEL");
+ break;
+ case LABEL_NOK_CERDO:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Label: NOK_CERDO");
+ break;
+ case LABEL_NOK_BCODE:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Label: NOK_BCODE");
+ break;
+ case LABEL_NOK_PRODUCT:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Label: NOK_PRODUCT");
+ break;
+ case LABEL_NOK_PRICE:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Label: NOK_PRICE");
+ break;
+ default:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Label: NOK");
+ break;
+ }
+ user_iface_log.lvl[user_iface_log.len] = 0;
+ (user_iface_log.len)++;
+}
+
+static int label_find (void)
+{
+ int status;
+
+ proc_load_mem(0);
+
+ proc_cmp(IMG_IFACE_CMP_BLUE);
+ proc_smooth(IMGI_SMOOTH_MEDIAN, 7);
+#if 0
+ proc_adaptive_threshold(CV_ADAPTIVE_THRESH_MEAN_C,
+ CV_THRESH_BINARY, 5);
+#else
+ proc_not();
+#endif
+ proc_smooth(IMGI_SMOOTH_MEAN, 21);
+ proc_threshold(cv::THRESH_BINARY_INV, 2);
+ proc_dilate_erode(100);
+ proc_contours(&contours, &hierarchy);
+
+ /* If no contour is found, error: NOK_LABEL */
+ if (!contours.size()) {
+ status = LABEL_NOK_LABEL;
+ return status;
+ }
+
+ proc_min_area_rect(&(contours[0]), &rect, true);
+
+ /* If angle is < -45º, it is taking into acount the incorrect side */
+ if (rect.angle < -45.0) {
+ int tmp;
+ rect.angle += 90.0;
+ tmp = rect.size.width;
+ rect.size.width = rect.size.height;
+ rect.size.height = tmp;
+ }
+
+ status = LABEL_OK;
+ return status;
+}
+
+static void label_align (void)
+{
+ proc_load_mem(0);
+
+ proc_rotate(&rect);
+ proc_cmp(IMG_IFACE_CMP_GREEN);
+ proc_save_mem(1);
+}
+
+static int find_cerdo (void)
+{
+ int status;
+
+ proc_load_mem(1);
+
+ int x;
+ int y;
+ int w;
+ int h;
+ x = rect.center.x - (1.05 * rect.size.width / 2);
+ if (x < 0) {
+ x = 0;
+ }
+ y = rect.center.y - (1.47 * rect.size.height / 2);
+ if (y < 0) {
+ y = 0;
+ }
+ w = rect.size.width / 2;
+ h = rect.size.height * 0.20;
+ proc_ROI(x, y, w, h);
+ proc_threshold(cv::THRESH_BINARY, IMG_IFACE_THR_OTSU);
+ proc_erode(1);
+ proc_OCR(IMG_IFACE_OCR_LANG_ENG, IMG_IFACE_OCR_CONF_NONE);
+
+ /* Compare Label text to "Cerdo". */
+ bool cerdo_nok;
+ cerdo_nok = strncmp(img_ocr_text, "Cerdo",
+ strlen("Cerdo"));
+
+ /* If string doesn't match, error: NOK_CERDO */
+ if (cerdo_nok) {
+ status = LABEL_NOK_CERDO;
+ return status;
+ }
+
+ status = LABEL_OK;
+ return status;
+}
+
+static int barcode_read (void)
+{
+ int status;
+
+ proc_load_mem(0);
+
+ proc_cmp(IMG_IFACE_CMP_GREEN);
+ proc_zbar(zbar::ZBAR_EAN13);
+
+ /* Check that 1 and only 1 bcode is read. */
+ if (zb_codes.n != 1) {
+ status = LABEL_NOK_BCODE;
+ return status;
+ }
+
+ status = LABEL_OK;
+ return status;
+}
+
+static int barcode_chk_prod (void)
+{
+ int status;
+
+ bool prod_nok;
+ prod_nok = strncmp(zb_codes.arr[0].data, "2301703",
+ strlen("2301703"));
+ if (prod_nok) {
+ status = LABEL_NOK_PRODUCT;
+ return status;
+ }
+
+ status = LABEL_OK;
+ return status;
+}
+
+static void price_read (void)
+{
+ proc_load_mem(1);
+
+ int x;
+ int y;
+ int w;
+ int h;
+ x = rect.center.x + (0.33 * rect.size.width / 2);
+ y = rect.center.y + (0.64 * rect.size.height / 2);
+ w = rect.size.width * 0.225;
+ h = rect.size.height * 0.15;
+ proc_ROI(x, y, w, h);
+ proc_smooth(IMGI_SMOOTH_MEAN, 3);
+ proc_threshold(cv::THRESH_BINARY, IMG_IFACE_THR_OTSU);
+ proc_dilate_erode(1);
+ proc_threshold(cv::THRESH_BINARY, 1);
+ proc_OCR(IMG_IFACE_OCR_LANG_DIGITS, IMG_IFACE_OCR_CONF_PRICE);
+}
+
+static int price_chk (void)
+{
+ int status;
+
+ char price [80];
+
+ /* Extract price from barcode */
+ if (zb_codes.arr[0].data[8] != '0') {
+ snprintf(price, 80, "%c%c.%c%c",
+ zb_codes.arr[0].data[8],
+ zb_codes.arr[0].data[9],
+ zb_codes.arr[0].data[10],
+ zb_codes.arr[0].data[11]);
+ } else {
+ snprintf(price, 80, "%c.%c%c",
+ zb_codes.arr[0].data[9],
+ zb_codes.arr[0].data[10],
+ zb_codes.arr[0].data[11]);
+ }
+
+ /* Compare price from barcode and from text */
+ bool price_nok;
+ price_nok = strncmp(img_ocr_text, price, strlen(price));
+
+ if (price_nok) {
+ status = LABEL_NOK_PRICE;
+ return status;
+ }
+
+ status = LABEL_OK;
+ return status;
+}
+
+
+/******************************************************************************
+ ******* end of file **********************************************************
+ ******************************************************************************/
diff --git a/modules/proc/src/proc_resistor.cpp b/modules/proc/src/proc_resistor.cpp
new file mode 100644
index 0000000..a90e5a6
--- /dev/null
+++ b/modules/proc/src/proc_resistor.cpp
@@ -0,0 +1,983 @@
+/******************************************************************************
+ * Copyright (C) 2018 Alejandro Colomar Andrés *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ******* headers **************************************************************
+ ******************************************************************************/
+/* Standard C ----------------------------------------------------------------*/
+ /* pow() */
+ #include <cmath>
+ /* snprintf() & fflush() */
+ #include <cstdio>
+
+/* Packages ------------------------------------------------------------------*/
+ /* openCV */
+ #include <opencv2/opencv.hpp>
+
+/* Project -------------------------------------------------------------------*/
+ /* CONSTANTS */
+ #include "img_iface.hpp"
+ /* user_iface_log */
+ #include "user_iface.hpp"
+
+/* Module --------------------------------------------------------------------*/
+ #include "proc_common.hpp"
+
+ #include "proc_resistor.hpp"
+
+
+/******************************************************************************
+ ******* structs **************************************************************
+ ******************************************************************************/
+struct Resistor_Bands {
+ /* position */
+ int x;
+ int y;
+
+ /* value */
+ unsigned char h;
+ unsigned char s;
+ unsigned char v;
+};
+
+
+/******************************************************************************
+ ******* variables ************************************************************
+ ******************************************************************************/
+/* Global --------------------------------------------------------------------*/
+
+/* Static --------------------------------------------------------------------*/
+static std::vector <std::vector <cv::Point_ <int>>> contours;
+static class cv::Mat hierarchy;
+static class cv::RotatedRect rect_rot;
+static class cv::Rect_ <int> rect;
+static int bkgd;
+static int bands_n;
+static struct Resistor_Bands bands [5];
+static char code [6];
+static int base;
+static float resistance;
+static int tolerance;
+
+
+/******************************************************************************
+ ******* static functions *****************************************************
+ ******************************************************************************/
+static void result_resistor (int status);
+
+static int resistor_find (void);
+static void resistor_align (void);
+static void resistor_dimensions_0 (void);
+static void resistor_crop_0 (void);
+static void resistor_bkgd (void);
+static void resistor_dimensions_1 (void);
+static void resistor_crop_1 (void);
+static void separate_bkgd_bands_h (void);
+static void separate_bkgd_bands_s (void);
+static void separate_bkgd_bands_v (void);
+static void bkgd_find (void);
+static int bands_find (void);
+static void bands_colors (void);
+static void bands_code (void);
+static char band_hsv2code (struct Resistor_Bands *band);
+static void resistor_value (void);
+static int resistor_tolerance (void);
+static int chk_std_value (void);
+
+
+/******************************************************************************
+ ******* global functions *****************************************************
+ ******************************************************************************/
+static int proc_resistor_ (void)
+{
+ int status;
+
+
+ proc_save_mem(0);
+ /* Find resistor (position and angle) */
+ {
+ /* Measure time */
+ clock_start();
+
+ status = resistor_find();
+ if (status) {
+ result_resistor(status);
+ return status;
+ }
+
+ /* Measure time */
+ clock_stop("Find resistor");
+ }
+ /* Align resistor, find its dimensions, and crop */
+ {
+ /* Measure time */
+ clock_start();
+
+ resistor_align();
+ resistor_dimensions_0();
+ resistor_crop_0();
+
+ /* Measure time */
+ clock_stop("Align, dimensions, & crop");
+ }
+ /* Find backgroung color */
+ {
+ /* Measure time */
+ clock_start();
+
+ resistor_bkgd();
+
+ /* Measure time */
+ clock_stop("Background color");
+ }
+ /* Crop more */
+ {
+ /* Measure time */
+ clock_start();
+
+ resistor_dimensions_1();
+ resistor_crop_1();
+
+ /* Measure time */
+ clock_stop("Crop more");
+ }
+ /* Separate background (BK) and lines (WH) */
+ {
+ /* Measure time */
+ clock_start();
+
+ separate_bkgd_bands_h();
+ separate_bkgd_bands_s();
+ separate_bkgd_bands_v();
+ bkgd_find();
+
+ /* Measure time */
+ clock_stop("Separate bkgd from bands");
+ }
+ /* Find bands: contours -> rectangles */
+ {
+ /* Measure time */
+ clock_start();
+
+ status = bands_find();
+ if (status) {
+ result_resistor(status);
+ return status;
+ }
+
+ /* Measure time */
+ clock_stop("Find bands");
+ }
+ /* Read values on the center of each band */
+ {
+ /* Measure time */
+ clock_start();
+
+ bands_colors();
+
+ /* Measure time */
+ clock_stop("Bands' colors");
+ }
+ /* Interpret colors */
+ {
+ /* Measure time */
+ clock_start();
+
+ bands_code();
+
+ /* Measure time */
+ clock_stop("Interpret colors");
+ }
+ /* Calculate resistor value & tolerance */
+ {
+ /* Measure time */
+ clock_start();
+
+ resistor_value();
+ status = resistor_tolerance();
+ if (status) {
+ result_resistor(status);
+ return status;
+ }
+
+ /* Write resistor value into log */
+ if (bands_n != 1) {
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Resistance: %.2E ± %i% Ohm",
+ resistance, tolerance);
+ } else {
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Resistance: 0 Ohm");
+ }
+ user_iface_log.lvl[user_iface_log.len] = 0;
+ (user_iface_log.len)++;
+
+ /* Measure time */
+ clock_stop("Calculate resistance & tolerance");
+ }
+ /* Check STD value */
+ {
+ /* Measure time */
+ clock_start();
+
+ status = chk_std_value();
+ if (status) {
+ result_resistor(status);
+ return status;
+ }
+
+ /* Measure time */
+ clock_stop("Chk STD values");
+ }
+
+ status = RESISTOR_OK;
+ result_resistor(status);
+ return status;
+}
+
+
+/******************************************************************************
+ ******* static functions *****************************************************
+ ******************************************************************************/
+static void result_resistor (int status)
+{
+ /* Cleanup */
+
+ /* Write result into log */
+ char result [LOG_LINE_LEN];
+ switch (status) {
+ case RESISTOR_OK:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Resistor: OK");
+ break;
+ case RESISTOR_NOK_RESISTOR:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Resistor: NOK_RESISTOR");
+ break;
+ case RESISTOR_NOK_BANDS:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Resistor: NOK_BANDS");
+ break;
+ case RESISTOR_NOK_STD_VALUE:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Resistor: NOK_STD_VALUE");
+ break;
+ case RESISTOR_NOK_TOLERANCE:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Resistor: NOK_TOLERANCE");
+ break;
+ default:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Resistor: NOK");
+ break;
+ }
+ user_iface_log.lvl[user_iface_log.len] = 0;
+ (user_iface_log.len)++;
+}
+
+int proc_resistor (void)
+{
+ int status;
+
+ proc_save_mem(0);
+ /* Find resistor (position and angle) */
+ {
+ /* Measure time */
+ clock_start();
+
+ status = resistor_find();
+ if (status) {
+ result_resistor(status);
+ return status;
+ }
+
+ /* Measure time */
+ clock_stop("Find resistor");
+ }
+ /* Align resistor, find its dimensions, and crop */
+ {
+ /* Measure time */
+ clock_start();
+
+ resistor_align();
+ resistor_dimensions_0();
+ resistor_crop_0();
+
+ /* Measure time */
+ clock_stop("Align, dimensions, & crop");
+ }
+ /* Find backgroung color */
+ {
+ /* Measure time */
+ clock_start();
+
+ resistor_bkgd();
+
+ /* Measure time */
+ clock_stop("Background color");
+ }
+ /* Crop more */
+ {
+ /* Measure time */
+ clock_start();
+
+ resistor_dimensions_1();
+ resistor_crop_1();
+
+ /* Measure time */
+ clock_stop("Crop more");
+ }
+ /* Separate background (BK) and bands (WH) */
+ {
+ /* Measure time */
+ clock_start();
+
+ separate_bkgd_bands_h();
+ separate_bkgd_bands_s();
+#if 0
+ separate_bkgd_bands_v();
+ bkgd_find();
+
+ /* Measure time */
+ clock_stop("Separate bkgd from bands");
+ }
+ /* Find bands: contours -> rectangles */
+ {
+ /* Measure time */
+ clock_start();
+
+ status = bands_find();
+ if (status) {
+ result_resistor(status);
+ return status;
+ }
+
+ /* Measure time */
+ clock_stop("Find bands");
+ }
+ /* Read values on the center of each band */
+ {
+ /* Measure time */
+ clock_start();
+
+ bands_colors();
+
+ /* Measure time */
+ clock_stop("Bands' colors");
+ }
+ /* Interpret colors */
+ {
+ /* Measure time */
+ clock_start();
+
+ bands_code();
+
+ /* Measure time */
+ clock_stop("Interpret colors");
+ }
+ /* Calculate resistor value & tolerance */
+ {
+ /* Measure time */
+ clock_start();
+
+ resistor_value();
+ status = resistor_tolerance();
+ if (status) {
+ result_resistor(status);
+ return status;
+ }
+
+ /* Write resistor value into log */
+ if (bands_n != 1) {
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Resistance: %.2E ± %i% Ohm",
+ resistance, tolerance);
+ } else {
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Resistance: 0 Ohm");
+ }
+ user_iface_log.lvl[user_iface_log.len] = 0;
+ (user_iface_log.len)++;
+
+ /* Measure time */
+ clock_stop("Calculate resistance & tolerance");
+ }
+ /* Check STD value */
+ {
+ /* Measure time */
+ clock_start();
+
+ status = chk_std_value();
+ if (status) {
+ result_resistor(status);
+ return status;
+ }
+
+ /* Measure time */
+ clock_stop("Chk STD values");
+#endif
+ }
+
+ proc_apply();
+ proc_save_file();
+
+ status = -1;
+ result_resistor(status);
+ return status;
+}
+
+static int resistor_find (void)
+{
+ int status;
+
+ proc_load_mem(0);
+
+ /* BGR -> HSV */
+ proc_cvt_color(cv::COLOR_BGR2HSV);
+ proc_save_mem(19);
+
+ proc_cmp(IMG_IFACE_CMP_SATURATION);
+ proc_smooth(IMGI_SMOOTH_MEDIAN, 7);
+ proc_threshold(cv::THRESH_BINARY, IMG_IFACE_THR_OTSU);
+ proc_save_mem(1);
+ proc_dilate_erode(10);
+ proc_contours(&contours, &hierarchy);
+
+ /* If no contour is found, error: NOK_RESISTOR */
+ if (!contours.size()) {
+ status = RESISTOR_NOK_RESISTOR;
+ return status;
+ }
+
+ proc_min_area_rect(&(contours[0]), &rect_rot, true);
+
+ /* If angle is < -45º, it is taking into acount the incorrect side */
+ if (rect_rot.angle < -45.0) {
+ rect_rot.angle += 90.0;
+ }
+
+ status = RESISTOR_OK;
+ return status;
+}
+
+static void resistor_align (void)
+{
+ proc_load_mem(19);
+ proc_rotate(&rect_rot);
+ proc_save_mem(2);
+ proc_load_mem(1);
+ proc_rotate(&rect_rot);
+ proc_save_mem(3);
+}
+
+static void resistor_dimensions_0 (void)
+{
+ proc_load_mem(3);
+
+ proc_contours(&contours, &hierarchy);
+ proc_bounding_rect(&(contours[0]), &rect, true);
+}
+
+static void resistor_crop_0 (void)
+{
+ proc_load_mem(2);
+
+ int x;
+ int y;
+ int w;
+ int h;
+ w = rect.width;
+ h = rect.height;
+ x = rect.x;
+ y = rect.y;
+ proc_ROI(x, y, w, h);
+ proc_save_mem(4);
+}
+
+static void resistor_bkgd (void)
+{
+ /* hue */
+ uint8_t bkgd_hue;
+ proc_load_mem(4);
+ proc_cmp(IMG_IFACE_CMP_HUE);
+ proc_median_vertical();
+ proc_median_horizontal();
+ proc_pixel_value(0, 0, &bkgd_hue);
+
+ /* saturation */
+ uint8_t bkgd_sat;
+ proc_load_mem(4);
+ proc_cmp(IMG_IFACE_CMP_SATURATION);
+ proc_median_vertical();
+ proc_median_horizontal();
+ proc_pixel_value(0, 0, &bkgd_sat);
+
+ if (bkgd_hue < 50) {
+ /* Beige */
+ bkgd = 0;
+ } else {
+ /* Blue */
+ if ((bkgd_hue <= 90) || (bkgd_sat <= 140)) {
+ /* Teal blue */
+ bkgd = 1;
+ } else if (bkgd_hue >= 105) {
+ /* Dark blue */
+ bkgd = 2;
+ } else {
+ /* Normal blue */
+ bkgd = 3;
+ }
+ }
+}
+
+static void resistor_dimensions_1 (void)
+{
+ proc_load_mem(3);
+
+ proc_dilate_erode(10);
+ proc_erode_dilate(rect.height / 1.9 - 9);
+ proc_contours(&contours, &hierarchy);
+ proc_bounding_rect(&(contours[0]), &rect, true);
+}
+
+static void resistor_crop_1 (void)
+{
+ proc_load_mem(2);
+
+ int x;
+ int y;
+ int w;
+ int h;
+ w = rect.width * 0.9;
+ h = rect.height * 0.9;
+ x = rect.x + w * (1.0 - 0.9) / 2.0;
+ y = rect.y + h * (1.0 - 0.9) / 2.0;
+ proc_ROI(x, y, w, h);
+ proc_save_mem(4);
+}
+
+static void separate_bkgd_bands_h (void)
+{
+ proc_load_mem(4);
+
+ proc_cmp(IMG_IFACE_CMP_HUE);
+ proc_median_vertical();
+ proc_save_mem(9);
+
+ switch (bkgd) {
+ case 0:
+ proc_threshold(cv::THRESH_TOZERO_INV, 20);
+ proc_threshold(cv::THRESH_TOZERO, 5);
+ break;
+ case 1:
+ proc_threshold(cv::THRESH_TOZERO_INV, 100);
+ proc_threshold(cv::THRESH_TOZERO, 70);
+ break;
+ case 2:
+ proc_threshold(cv::THRESH_TOZERO_INV, 115);
+ proc_threshold(cv::THRESH_TOZERO, 100);
+ break;
+ case 3:
+ proc_threshold(cv::THRESH_TOZERO_INV, 110);
+ proc_threshold(cv::THRESH_TOZERO, 90);
+ break;
+ }
+ proc_threshold(cv::THRESH_BINARY_INV, 1);
+ proc_save_mem(5);
+}
+
+static void separate_bkgd_bands_s (void)
+{
+ proc_load_mem(4);
+
+ proc_cmp(IMG_IFACE_CMP_SATURATION);
+ proc_median_vertical();
+ proc_save_mem(10);
+
+ switch (bkgd) {
+
+ case 0:
+ proc_threshold(cv::THRESH_TOZERO, 100);
+ break;
+ case 1:
+ proc_threshold(cv::THRESH_TOZERO, 95);
+ break;
+ case 2:
+ proc_threshold(cv::THRESH_TOZERO, 200);
+ break;
+ case 3:
+ proc_threshold(cv::THRESH_TOZERO, 130);
+ break;
+ }
+ proc_threshold(cv::THRESH_BINARY_INV, 1);
+ proc_save_mem(6);
+}
+
+static void separate_bkgd_bands_v (void)
+{
+ proc_load_mem(4);
+
+ proc_cmp(IMG_IFACE_CMP_VALUE);
+ proc_median_vertical();
+ proc_save_mem(11);
+
+ switch (bkgd) {
+ case 0:
+ proc_threshold(cv::THRESH_TOZERO_INV, 130);
+ proc_threshold(cv::THRESH_TOZERO, 65);
+ break;
+
+ case 1:
+ proc_threshold(cv::THRESH_TOZERO_INV, 155);
+ proc_threshold(cv::THRESH_TOZERO, 60);
+ break;
+ case 2:
+
+ proc_threshold(cv::THRESH_TOZERO_INV, 140);
+ proc_threshold(cv::THRESH_TOZERO, 60);
+ break;
+ case 3:
+ proc_threshold(cv::THRESH_TOZERO_INV, 165);
+ proc_threshold(cv::THRESH_TOZERO, 45);
+ break;
+ }
+ proc_threshold(cv::THRESH_BINARY_INV, 1);
+ proc_save_mem(7);
+}
+
+static void bkgd_find (void)
+{
+ /* Merge the components: H | S | V */
+ proc_load_mem(7);
+ proc_save_ref();
+ proc_load_mem(6);
+ proc_or_2ref();
+ proc_save_ref();
+ proc_load_mem(5);
+ proc_or_2ref();
+ proc_dilate_erode(1);
+ proc_save_mem(8);
+}
+
+static int bands_find (void)
+{
+ int status;
+
+ proc_load_mem(8);
+
+ /* Contours */
+ proc_contours(&contours, &hierarchy);
+
+ bands_n = contours.size();
+ if ((bands_n == 0) || (bands_n == 2) || (bands_n > 5)) {
+ status = RESISTOR_NOK_BANDS;
+ return status;
+ }
+
+ /* Band 0 (hundreds) */
+ if (bands_n == 5) {
+ proc_bounding_rect(&(contours[4]), &rect, true);
+ bands[0].x = rect.x + rect.width / 2.0;
+ bands[0].y = rect.y + rect.height / 2.0;
+ }
+
+ /* Band 1 (tens) */
+ if (bands_n >= 3) {
+ if (bands_n > 3) {
+ proc_bounding_rect(&(contours[3]), &rect, true);
+ } else {
+ proc_bounding_rect(&(contours[2]), &rect, true);
+ }
+ bands[1].x = rect.x + rect.width / 2.0;
+ bands[1].y = rect.y + rect.height / 2.0;
+ }
+
+ /* Band 2 (units) */
+ if (bands_n > 3) {
+ proc_bounding_rect(&(contours[2]), &rect, true);
+ } else if (bands_n == 3) {
+ proc_bounding_rect(&(contours[1]), &rect, true);
+ } else { /* bands_n == 1 */
+ proc_bounding_rect(&(contours[0]), &rect, true);
+ }
+ bands[2].x = rect.x + rect.width / 2.0;
+ bands[2].y = rect.y + rect.height / 2.0;
+
+ /* Band 3 (multiplier) */
+ if (bands_n >= 3) {
+ if (bands_n > 3) {
+ proc_bounding_rect(&(contours[1]), &rect, true);
+ } else {
+ proc_bounding_rect(&(contours[0]), &rect, true);
+ }
+ bands[3].x = rect.x + rect.width / 2.0;
+ bands[3].y = rect.y + rect.height / 2.0;
+ }
+
+ /* Band 4 (tolerance) */
+ if (bands_n > 3) {
+ proc_bounding_rect(&(contours[0]), &rect, true);
+ bands[4].x = rect.x + rect.width / 2.0;
+ bands[4].y = rect.y + rect.height / 2.0;
+ }
+}
+
+static void bands_colors (void)
+{
+ /* Hue */
+ proc_load_mem(9);
+ if (bands_n == 5) {
+ proc_pixel_value(bands[0].x, bands[0].y, &(bands[0].h));
+ }
+ if (bands_n >= 3) {
+ proc_pixel_value(bands[1].x, bands[1].y, &(bands[1].h));
+ }
+ proc_pixel_value(bands[2].x, bands[2].y, &(bands[2].h));
+ if (bands_n >= 3) {
+ proc_pixel_value(bands[3].x, bands[3].y, &(bands[3].h));
+ }
+ if (bands_n > 3) {
+ proc_pixel_value(bands[4].x, bands[4].y, &(bands[4].h));
+ }
+
+ /* Saturation */
+ proc_load_mem(10);
+ if (bands_n == 5) {
+ proc_pixel_value(bands[0].x, bands[0].y, &(bands[0].s));
+ }
+ if (bands_n >= 3) {
+ proc_pixel_value(bands[1].x, bands[1].y, &(bands[1].s));
+ }
+ proc_pixel_value(bands[2].x, bands[2].y, &(bands[2].s));
+ if (bands_n >= 3) {
+ proc_pixel_value(bands[3].x, bands[3].y, &(bands[3].s));
+ }
+ if (bands_n > 3) {
+ proc_pixel_value(bands[4].x, bands[4].y, &(bands[4].s));
+ }
+
+ /* Value */
+ proc_load_mem(11);
+ if (bands_n == 5) {
+ proc_pixel_value(bands[0].x, bands[0].y, &(bands[0].v));
+ }
+ if (bands_n >= 3) {
+ proc_pixel_value(bands[1].x, bands[1].y, &(bands[1].v));
+ }
+ proc_pixel_value(bands[2].x, bands[2].y, &(bands[2].v));
+ if (bands_n >= 3) {
+ proc_pixel_value(bands[3].x, bands[3].y, &(bands[3].v));
+ }
+ if (bands_n > 3) {
+ proc_pixel_value(bands[4].x, bands[4].y, &(bands[4].v));
+ }
+}
+
+static void bands_code (void)
+{
+ /* Init to 0 */
+ int i;
+ for (i = 0; i < 6; i++) {
+ code[i] = '\0';
+ }
+
+ /* Band 0 (hundreds) */
+ if (bands_n == 5) {
+ code[0] = band_hsv2code(&bands[0]);
+ } else {
+ code[0] = 'n';
+ }
+
+
+ /* Band 1 (tens) */
+ if (bands_n != 1) {
+ code[1] = band_hsv2code(&bands[1]);
+ } else {
+ code[1] = 'n';
+ }
+
+ /* Band 2 (units) */
+ code[2] = band_hsv2code(&bands[2]);
+
+ /* Band 3 (multiplier) */
+ if (bands_n != 1) {
+ code[3] = band_hsv2code(&bands[3]);
+ } else {
+ code[3] = 'n';
+ }
+
+ /* Band 4 (tolerance) */
+ if (bands_n > 3) {
+ code[4] = band_hsv2code(&bands[4]);
+ } else {
+ code[4] = 'n';
+ }
+
+ /* Write bands' code into log */
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Code: \"%s\"",
+ code);
+ user_iface_log.lvl[user_iface_log.len] = 0;
+ (user_iface_log.len)++;
+}
+
+static char band_hsv2code (struct Resistor_Bands *band)
+{
+ char ch;
+
+ if (band->v < 24) {
+ ch = '0';
+ } else if (band->v < 28) {
+ if ((band->h < 90) || (band->h > 135)) {
+ ch = '1';
+ } else if (band->s < 78) {
+ ch = '1';
+ } else {
+ ch = '0';
+ }
+ } else if (band->v < 50) {
+ if ((band->h > 120) || (band->h < 10)) {
+ ch = '1';
+ } else if (band->h < 85) {
+ ch = '5';
+ } else {
+ ch = '8';
+ }
+ } else if (band->v < 70) {
+ if (band->h < 90) {
+ ch = '3';
+ } else {
+ ch = '2';
+ }
+ } else if (band->v < 100) {
+ if (band->h < 10) {
+ ch = '3';
+ } else if (band->h < 40) {
+ ch = 'g';
+ } else if (band->h < 85) {
+ ch = '4';
+ } else if (band->h < 140) {
+ ch = '6';
+ } else {
+ ch = '2';
+ }
+ } else {
+ if (band->h < 45) {
+ ch = '3';
+ } else if (band->h < 105) {
+ ch = '9';
+ } else if (band->h < 140) {
+ ch = '7';
+ } else {
+ ch = '2';
+ }
+ }
+
+ return ch;
+}
+
+static void resistor_value (void)
+{
+ /* Base value */
+ base = code[2] - '0';
+ if (code[1] != 'n') {
+ base += (code[1] - '0') * 10;
+ }
+ if (code[0] != 'n') {
+ base += (code[0] - '0') * 100;
+ }
+
+ /* Calculate resistance */
+ int power;
+ if ((code[3] > '0') && (code[3] < '9')) {
+ power = code[3] - '0';
+ } else if (code[3] == 'g') {
+ power = -1;
+ } else if (code[3] == 's') {
+ power = -2;
+ }
+ resistance = base * pow(10, power);
+}
+
+static int resistor_tolerance (void)
+{
+ int status;
+
+ if (bands_n != 1) {
+ switch (code[4]) {
+ case '1':
+ tolerance = 1;
+ break;
+ case '2':
+ tolerance = 2;
+ break;
+ case '4':
+ case 'g':
+ case 'n':
+ tolerance = 5;
+ break;
+ case '8':
+ tolerance = 10;
+ break;
+ default:
+ status = RESISTOR_NOK_TOLERANCE;
+ return status;
+ }
+ }
+
+ status = RESISTOR_OK;
+ return status;
+}
+
+static int chk_std_value (void)
+{
+ int status;
+
+ /* Check that base value is a standard value */
+ int std_values_10 [12] = {10,12,15,18,22,27,33,39,47,56,68,82};
+ int std_values_5 [12] = {11,13,16,20,24,30,36,43,51,62,75,91};
+
+ bool std_value_nok;
+ std_value_nok = true;
+
+ int i;
+ if (bands_n != 1) {
+ for (i = 0; i < 12; i++) {
+ if (base == std_values_10[i]) {
+ std_value_nok = false;
+ }
+ if (base == (std_values_10[i] * 10)) {
+ std_value_nok = false;
+ }
+ }
+ if (tolerance <= 5) {
+ for (i = 0; i < 12; i++) {
+ if (base == std_values_5[i]) {
+ std_value_nok = false;
+ }
+ if (base == (std_values_5[i] * 10)) {
+ std_value_nok = false;
+ }
+ }
+ }
+ } else {
+ if (base == 0) {
+ std_value_nok = false;
+ }
+ }
+
+ if (std_value_nok) {
+ status = RESISTOR_NOK_STD_VALUE;
+ return status;
+ }
+
+ status = RESISTOR_OK;
+ return status;
+}
+
+
+/******************************************************************************
+ ******* end of file **********************************************************
+ ******************************************************************************/
diff --git a/modules/proc/tmp/Makefile b/modules/proc/tmp/Makefile
index 44abdf8..7957f0e 100644
--- a/modules/proc/tmp/Makefile
+++ b/modules/proc/tmp/Makefile
@@ -10,30 +10,74 @@ IMG_INC_DIR = $(IMG_DIR)/inc/
SAVE_INC_DIR = $(SAVE_DIR)/inc/
USR_INC_DIR = $(USR_DIR)/inc/
-INC_DIR = $(PROC_DIR)/inc/
-SRC_DIR = $(PROC_DIR)/src/
+INC_DIR = $(PROC_DIR)/inc/
+SRC_DIR = $(PROC_DIR)/src/
# dependencies
-_ALL = proc.o
+_ALL = proc_label.o proc_coins.o proc_resistor.o proc_common.o proc_iface.o
ALL = $(_ALL) proc_mod.o
-PROC_INC_LIBALX = alx_input.hpp
-PROC_INC_IMG = img_iface.hpp
-PROC_INC_SAVE = save.hpp
-PROC_INC_USER = user_iface.hpp
-PROC_INC = proc.hpp
-PROC_DEPS = $(SRC_DIR)/proc.cpp \
- $(patsubst %,$(INC_DIR)/%,$(PROC_INC)) \
- $(patsubst %,$(IMG_INC_DIR)/%,$(PROC_INC_IMG)) \
- $(patsubst %,$(SAVE_INC_DIR)/%,$(PROC_INC_SAVE)) \
- $(patsubst %,$(USR_INC_DIR)/%,$(PROC_INC_USR)) \
- $(patsubst %,$(LIBALX_INC_DIR)/%,$(PROC_INC_LIBALX))
-PROC_INC_DIRS = -I $(INC_DIR) \
- -I $(IMG_INC_DIR) \
- -I $(SAVE_INC_DIR) \
- -I $(USR_INC_DIR) \
- -I $(LIBALX_INC_DIR)
+PROC_LAB_INC_IMG = img_iface.hpp
+PROC_LAB_INC_USER = user_iface.hpp
+PROC_LAB_INC = proc_label.hpp proc_common.hpp
+PROC_LAB_DEPS = $(SRC_DIR)/proc_label.cpp \
+ $(patsubst %,$(INC_DIR)/%,$(PROC_INC)) \
+ $(patsubst %,$(IMG_INC_DIR)/%,$(PROC_INC_IMG)) \
+ $(patsubst %,$(USR_INC_DIR)/%,$(PROC_INC_USR))
+PROC_LAB_INC_DIRS = -I $(INC_DIR) \
+ -I $(IMG_INC_DIR) \
+ -I $(USR_INC_DIR)
+
+PROC_COIN_INC_IMG = img_iface.hpp
+PROC_COIN_INC_USER = user_iface.hpp
+PROC_COIN_INC = proc_coins.hpp proc_common.hpp
+PROC_COIN_DEPS = $(SRC_DIR)/proc_coins.cpp \
+ $(patsubst %,$(INC_DIR)/%,$(PROC_INC)) \
+ $(patsubst %,$(IMG_INC_DIR)/%,$(PROC_INC_IMG)) \
+ $(patsubst %,$(USR_INC_DIR)/%,$(PROC_INC_USR))
+PROC_COIN_INC_DIRS = -I $(INC_DIR) \
+ -I $(IMG_INC_DIR) \
+ -I $(USR_INC_DIR)
+
+PROC_RES_INC_IMG = img_iface.hpp
+PROC_RES_INC_USER = user_iface.hpp
+PROC_RES_INC = proc_resistor.hpp proc_common.hpp
+PROC_RES_DEPS = $(SRC_DIR)/proc_resistor.cpp \
+ $(patsubst %,$(INC_DIR)/%,$(PROC_INC)) \
+ $(patsubst %,$(IMG_INC_DIR)/%,$(PROC_INC_IMG)) \
+ $(patsubst %,$(USR_INC_DIR)/%,$(PROC_INC_USR))
+PROC_RES_INC_DIRS = -I $(INC_DIR) \
+ -I $(IMG_INC_DIR) \
+ -I $(USR_INC_DIR)
+
+PROC_CMN_INC_IMG = img_iface.hpp
+PROC_CMN_INC_USER = user_iface.hpp
+PROC_CMN_INC = proc_common.hpp
+PROC_CMN_DEPS = $(SRC_DIR)/proc_common.cpp \
+ $(patsubst %,$(INC_DIR)/%,$(PROC_INC)) \
+ $(patsubst %,$(IMG_INC_DIR)/%,$(PROC_INC_IMG)) \
+ $(patsubst %,$(USR_INC_DIR)/%,$(PROC_INC_USR))
+PROC_CMN_INC_DIRS = -I $(INC_DIR) \
+ -I $(IMG_INC_DIR) \
+ -I $(USR_INC_DIR)
+
+PROC_IFACE_INC_IMG = img_iface.h
+PROC_IFACE_INC_LIBALX = alx_input.h
+PROC_IFACE_INC_SAVE = save.h
+PROC_IFACE_INC_USER = user_iface.h
+PROC_IFACE_INC = proc_iface.h proc_label.h proc_coins.h proc_resistor.h
+PROC_IFACE_DEPS = $(SRC_DIR)/proc_iface.c \
+ $(patsubst %,$(INC_DIR)/%,$(PROC_INC)) \
+ $(patsubst %,$(IMG_INC_DIR)/%,$(PROC_INC_IMG)) \
+ $(patsubst %,$(SAVE_INC_DIR)/%,$(PROC_INC_SAVE)) \
+ $(patsubst %,$(USR_INC_DIR)/%,$(PROC_INC_USR)) \
+ $(patsubst %,$(LIBALX_INC_DIR)/%,$(PROC_INC_LIBALX))
+PROC_IFACE_INC_DIRS = -I $(INC_DIR) \
+ -I $(IMG_INC_DIR) \
+ -I $(SAVE_INC_DIR) \
+ -I $(USR_INC_DIR) \
+ -I $(LIBALX_INC_DIR)
# target: dependencies
# action
@@ -47,10 +91,38 @@ proc_mod.o: $(_ALL)
@echo ""
-proc.s: $(PROC_DEPS)
- $(Q)$(CXX) $(CXXFLAGS) $(PROC_INC_DIRS) -S $< -o $@
+proc_label.s: $(PROC_LAB_DEPS)
+ $(Q)$(CXX) $(CXXFLAGS) $(PROC_LAB_INC_DIRS) -S $< -o $@
@echo " CXX $@"
-proc.o: proc.s
+proc_label.o: proc_label.s $(PROC_LAB_DEPS)
+ $(Q)$(AS) $< -o $@
+ @echo " AS $@"
+
+proc_coins.s: $(PROC_COIN_DEPS)
+ $(Q)$(CXX) $(CXXFLAGS) $(PROC_COIN_INC_DIRS) -S $< -o $@
+ @echo " CXX $@"
+proc_coins.o: proc_coins.s $(PROC_COIN_DEPS)
+ $(Q)$(AS) $< -o $@
+ @echo " AS $@"
+
+proc_resistor.s: $(PROC_RES_DEPS)
+ $(Q)$(CXX) $(CXXFLAGS) $(PROC_RES_INC_DIRS) -S $< -o $@
+ @echo " CXX $@"
+proc_resistor.o: proc_resistor.s $(PROC_RES_DEPS)
+ $(Q)$(AS) $< -o $@
+ @echo " AS $@"
+
+proc_common.s: $(PROC_CMN_DEPS)
+ $(Q)$(CXX) $(CXXFLAGS) $(PROC_CMN_INC_DIRS) -S $< -o $@
+ @echo " CXX $@"
+proc_common.o: proc_common.s $(PROC_CMN_DEPS)
+ $(Q)$(AS) $< -o $@
+ @echo " AS $@"
+
+proc_iface.s: $(PROC_IFACE_DEPS)
+ $(Q)$(CC) $(CFLAGS) $(PROC_IFACE_INC_DIRS) -S $< -o $@
+ @echo " CC $@"
+proc_iface.o: proc_iface.s $(PROC_IFACE_DEPS)
$(Q)$(AS) $< -o $@
@echo " AS $@"
diff --git a/modules/user/src/user_iface.c b/modules/user/src/user_iface.c
index c35d2c2..d196097 100644
--- a/modules/user/src/user_iface.c
+++ b/modules/user/src/user_iface.c
@@ -16,7 +16,7 @@
/* img_iface_act_nodata() */
#include "img_iface.h"
/* proc_iface() */
- #include "proc.h"
+ #include "proc_iface.h"
/* Module --------------------------------------------------------------------*/
/* user_clui() & ...save_name() */
diff --git a/modules/user/tmp/Makefile b/modules/user/tmp/Makefile
index b8e9c25..2dc948f 100644
--- a/modules/user/tmp/Makefile
+++ b/modules/user/tmp/Makefile
@@ -20,7 +20,7 @@ _ALL = user_iface.o user_clui.o user_tui.o
ALL = $(_ALL) user_mod.o
UI_INC_IMG = img_iface.h
-UI_INC_PROC = proc.h
+UI_INC_PROC = proc_iface.h
UI_INC = user_iface.h user_clui.h user_tui.h
UI_DEPS = $(SRC_DIR)/user_iface.c \
$(patsubst %,$(INC_DIR)/%,$(UI_INC)) \