summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralex <alex@ASUS>2018-10-18 03:30:37 +0200
committeralex <alex@ASUS>2018-10-18 03:30:37 +0200
commitc45faf870b252003a9074fb6861a9d20509da009 (patch)
tree910dd42db686335df10462c53685e1c2ddef3ad0
parent21c9b9adc6c92f493bd47b8cec6f1429dcd84960 (diff)
Add contours_size
-rw-r--r--modules/image/inc/img_cv.h1
-rw-r--r--modules/image/inc/img_iface.h62
-rw-r--r--modules/image/inc/img_iface.hpp64
-rw-r--r--modules/image/src/img_cv.c49
-rw-r--r--modules/image/src/img_iface.c95
-rw-r--r--modules/image/src/img_orb.cpp2
-rw-r--r--modules/proc/inc/proc.h2
-rw-r--r--modules/proc/src/proc.c608
-rw-r--r--modules/user/inc/user_iface.h1
-rw-r--r--modules/user/inc/user_iface.hpp1
-rw-r--r--modules/user/src/user_iface.c6
-rw-r--r--modules/user/src/user_tui.c8
12 files changed, 583 insertions, 316 deletions
diff --git a/modules/image/inc/img_cv.h b/modules/image/inc/img_cv.h
index d124707..ee2adb7 100644
--- a/modules/image/inc/img_cv.h
+++ b/modules/image/inc/img_cv.h
@@ -33,6 +33,7 @@
IMG_CV_ACT_DILATE,
IMG_CV_ACT_ERODE,
IMG_CV_ACT_CONTOURS,
+ IMG_CV_ACT_CONTOURS_SIZE,
IMG_CV_ACT_MIN_AREA_RECT,
IMG_CV_ACT_ROTATE_ORTO,
IMG_CV_ACT_ROTATE,
diff --git a/modules/image/inc/img_iface.h b/modules/image/inc/img_iface.h
index b24e999..2ff4802 100644
--- a/modules/image/inc/img_iface.h
+++ b/modules/image/inc/img_iface.h
@@ -21,9 +21,12 @@
/******************************************************************************
******* macros ***************************************************************
******************************************************************************/
- # define OCR_TEXT_MAX (1048576)
- # define ZB_CODES_MAX (10)
- # define ZBAR_LEN_MAX (1048576)
+ # define CONTOURS_MAX (65536)
+ # define OCR_TEXT_MAX (1048576)
+ # define ZB_CODES_MAX (10)
+ # define ZBAR_LEN_MAX (1048576)
+
+ # define IMG_IFACE_THR_OTSU (-1)
/******************************************************************************
@@ -42,6 +45,7 @@
IMG_IFACE_ACT_DILATE,
IMG_IFACE_ACT_ERODE,
IMG_IFACE_ACT_CONTOURS,
+ IMG_IFACE_ACT_CONTOURS_SIZE,
IMG_IFACE_ACT_MIN_AREA_RECT,
IMG_IFACE_ACT_ROTATE_ORTO,
IMG_IFACE_ACT_ROTATE,
@@ -73,47 +77,72 @@
IMG_IFACE_ACT_SAVE_FILE
};
+ enum Img_Iface_Cmp {
+ IMG_IFACE_CMP_BLUE = 0,
+ IMG_IFACE_CMP_GREEN,
+ IMG_IFACE_CMP_RED
+ };
+
+ enum Img_Iface_OCR_Lang {
+ IMG_IFACE_OCR_LANG_ENG = 0,
+ IMG_IFACE_OCR_LANG_SPA,
+ IMG_IFACE_OCR_LANG_CAT
+ };
+
+ enum Img_Iface_OCR_Conf {
+ IMG_IFACE_OCR_CONF_NONE = 0,
+ IMG_IFACE_OCR_CONF_PRICE
+ };
+
/******************************************************************************
******* structs **************************************************************
******************************************************************************/
/* img_cv --------------------------------------------------------------------*/
struct Img_Iface_Data_Component {
- int cmp;
+ int cmp;
};
struct Img_Iface_Data_Smooth {
- int method;
- int msk_siz;
+ int method;
+ int msk_siz;
};
struct Img_Iface_Data_Threshold {
- int thr_typ;
- int thr_val;
+ int thr_typ;
+ int thr_val;
};
struct Img_Iface_Data_Adaptive_Thr {
- int method;
- int thr_typ;
- int nbh_val;
+ int method;
+ int thr_typ;
+ int nbh_val;
};
struct Img_Iface_Data_Dilate_Erode {
- int i;
+ int i;
};
struct Img_Iface_Data_Contours {
struct CvMemStorage **storage;
struct CvSeq **contours;
+ int *n;
+ };
+
+ struct Img_Iface_Data_Contours_Size {
+ struct CvSeq *contours;
+ int n;
+ double area [CONTOURS_MAX];
+ double perimeter [CONTOURS_MAX];
};
struct Img_Iface_Data_MinARect {
- struct CvSeq **contours;
+ struct CvSeq *contours;
struct CvBox2D *rect;
};
struct Img_Iface_Data_Rotate_Orto {
- int n;
+ int n;
};
struct Img_Iface_Data_Rotate {
@@ -122,7 +151,7 @@
};
struct Img_Iface_Data_SetROI {
- struct CvRect rect;
+ struct CvRect rect;
};
/* img_zbar -------------------------------------------------------------------*/
@@ -159,7 +188,8 @@
void img_iface_cleanup_main (void);
struct _IplImage *img_iface_load (void);
void img_iface_cleanup (void);
- struct _IplImage *img_iface_act (int action, void *data);
+ void img_iface_act (int action, void *data);
+ struct _IplImage *img_iface_show (void);
/******************************************************************************
diff --git a/modules/image/inc/img_iface.hpp b/modules/image/inc/img_iface.hpp
index c16650e..7b98327 100644
--- a/modules/image/inc/img_iface.hpp
+++ b/modules/image/inc/img_iface.hpp
@@ -27,9 +27,12 @@ extern "C" {
/******************************************************************************
******* macros ***************************************************************
******************************************************************************/
- # define OCR_TEXT_MAX (1048576)
- # define ZB_CODES_MAX (10)
- # define ZBAR_LEN_MAX (1048576)
+ # define CONTOURS_MAX (65536)
+ # define OCR_TEXT_MAX (1048576)
+ # define ZB_CODES_MAX (10)
+ # define ZBAR_LEN_MAX (1048576)
+
+ # define IMG_IFACE_THR_OTSU (-1)
/******************************************************************************
@@ -48,6 +51,7 @@ extern "C" {
IMG_IFACE_ACT_DILATE,
IMG_IFACE_ACT_ERODE,
IMG_IFACE_ACT_CONTOURS,
+ IMG_IFACE_ACT_CONTOURS_SIZE,
IMG_IFACE_ACT_MIN_AREA_RECT,
IMG_IFACE_ACT_ROTATE_ORTO,
IMG_IFACE_ACT_ROTATE,
@@ -79,47 +83,72 @@ extern "C" {
IMG_IFACE_ACT_SAVE_FILE
};
+ enum Img_Iface_Cmp {
+ IMG_IFACE_CMP_BLUE = 0,
+ IMG_IFACE_CMP_GREEN,
+ IMG_IFACE_CMP_RED
+ };
+
+ enum Img_Iface_OCR_Lang {
+ IMG_IFACE_OCR_LANG_ENG = 0,
+ IMG_IFACE_OCR_LANG_SPA,
+ IMG_IFACE_OCR_LANG_CAT
+ };
+
+ enum Img_Iface_OCR_Conf {
+ IMG_IFACE_OCR_CONF_NONE = 0,
+ IMG_IFACE_OCR_CONF_PRICE
+ };
+
/******************************************************************************
******* structs **************************************************************
******************************************************************************/
/* img_cv --------------------------------------------------------------------*/
struct Img_Iface_Data_Component {
- int cmp;
+ int cmp;
};
struct Img_Iface_Data_Smooth {
- int method;
- int msk_siz;
+ int method;
+ int msk_siz;
};
struct Img_Iface_Data_Threshold {
- int thr_typ;
- int thr_val;
+ int thr_typ;
+ int thr_val;
};
struct Img_Iface_Data_Adaptive_Thr {
- int method;
- int thr_typ;
- int nbh_val;
+ int method;
+ int thr_typ;
+ int nbh_val;
};
struct Img_Iface_Data_Dilate_Erode {
- int i;
+ int i;
};
struct Img_Iface_Data_Contours {
struct CvMemStorage **storage;
struct CvSeq **contours;
+ int *n;
+ };
+
+ struct Img_Iface_Data_Contours_Size {
+ struct CvSeq *contours;
+ int n;
+ double area [CONTOURS_MAX];
+ double perimeter [CONTOURS_MAX];
};
struct Img_Iface_Data_MinARect {
- struct CvSeq **contours;
- struct CvBox2D *rect;
+ struct CvSeq *contours;
+ struct CvBox2D *rect;
};
struct Img_Iface_Data_Rotate_Orto {
- int n;
+ int n;
};
struct Img_Iface_Data_Rotate {
@@ -128,7 +157,7 @@ extern "C" {
};
struct Img_Iface_Data_SetROI {
- struct CvRect rect;
+ struct CvRect rect;
};
/* img_zbar -------------------------------------------------------------------*/
@@ -165,7 +194,8 @@ extern "C" {
void img_iface_cleanup_main (void);
struct _IplImage *img_iface_load (void);
void img_iface_cleanup (void);
- struct _IplImage *img_iface_act (int action, void *data);
+ void img_iface_act (int action, void *data);
+ struct _IplImage *img_iface_show (void);
/******************************************************************************
diff --git a/modules/image/src/img_cv.c b/modules/image/src/img_cv.c
index 456b0f2..6632bed 100644
--- a/modules/image/src/img_cv.c
+++ b/modules/image/src/img_cv.c
@@ -7,6 +7,8 @@
******* headers **************************************************************
******************************************************************************/
/* Standard C ----------------------------------------------------------------*/
+ /* true & false */
+ #include <stdbool.h>
/* snprintf() */
#include <stdio.h>
@@ -38,6 +40,7 @@ static void img_cv_adaptive_thr (struct _IplImage *imgptr, void *data);
static void img_cv_dilate (struct _IplImage *imgptr, void *data);
static void img_cv_erode (struct _IplImage *imgptr, void *data);
static void img_cv_contours (struct _IplImage **imgptr2, void *data);
+static void img_cv_contours_size (void *data);
static void img_cv_min_area_rect (struct _IplImage *imgptr, void *data);
static void img_cv_rotate_orto (struct _IplImage **imgptr2, void *data);
static void img_cv_rotate (struct _IplImage *imgptr, void *data);
@@ -84,6 +87,9 @@ void img_cv_act (struct _IplImage **imgptr2, int action, void *data)
case IMG_CV_ACT_CONTOURS:
img_cv_contours(imgptr2, data);
break;
+ case IMG_CV_ACT_CONTOURS_SIZE:
+ img_cv_contours_size(data);
+ break;
case IMG_CV_ACT_MIN_AREA_RECT:
img_cv_min_area_rect(*imgptr2, data);
break;
@@ -305,12 +311,18 @@ static void img_cv_contours (struct _IplImage **imgptr2, void *data)
storage = data_cast->storage;
struct CvSeq **contours;
contours = data_cast->contours;
+ int *n;
+ n = data_cast->n;
/* Get contours */
- int i;
- i = cvFindContours(*imgptr2, *storage, contours, sizeof(CvContour),
+ *n = cvFindContours(*imgptr2, *storage, contours, sizeof(CvContour),
CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, cvPoint(0, 0));
+ /* Limit n */
+ if (*n > CONTOURS_MAX) {
+ *n = CONTOURS_MAX;
+ }
+
/* Draw contours in color */
cvDrawContours(imgtmp, *contours, CV_RGB(255, 0, 0), CV_RGB(0, 255, 0),
1, 1, 8, cvPoint(0, 0));
@@ -320,7 +332,34 @@ static void img_cv_contours (struct _IplImage **imgptr2, void *data)
*imgptr2 = cvCloneImage(imgtmp);
/* clean up */
- cvReleaseImage(&imgtmp);
+ cvReleaseImage(&imgtmp);
+}
+
+static void img_cv_contours_size (void *data)
+{
+ /* Data */
+ struct Img_Iface_Data_Contours_Size *data_cast;
+ data_cast = (struct Img_Iface_Data_Contours_Size *)data;
+
+ /* Contours */
+ struct CvSeq *contours;
+ contours = data_cast->contours;
+ int n;
+ n = data_cast->n;
+
+ /* Get area and perimeter */
+ int i;
+ for (i = 0; i < n; i++) {
+ if (!contours) {
+ break;
+ }
+
+ data_cast->area[i] = cvContourArea(contours,
+ CV_WHOLE_SEQ, false);
+ data_cast->perimeter[i] = cvArcLength(contours,
+ CV_WHOLE_SEQ, -1);
+ contours = contours->h_next;
+ }
}
static void img_cv_min_area_rect (struct _IplImage *imgptr, void *data)
@@ -330,14 +369,14 @@ static void img_cv_min_area_rect (struct _IplImage *imgptr, void *data)
data_cast = (struct Img_Iface_Data_MinARect *)data;
/* Contours */
- struct CvSeq **contours;
+ struct CvSeq *contours;
contours = data_cast->contours;
/* Rotated rectangle */
struct CvBox2D *rect;
rect = data_cast->rect;
/* Get rectangle */
- *rect = cvMinAreaRect2(*contours, NULL);
+ *rect = cvMinAreaRect2(contours, NULL);
/* Draw rectangle */
struct CvPoint2D32f points[4];
diff --git a/modules/image/src/img_iface.c b/modules/image/src/img_iface.c
index 11d1b6e..d432aea 100644
--- a/modules/image/src/img_iface.c
+++ b/modules/image/src/img_iface.c
@@ -56,14 +56,13 @@ static struct _IplImage *image_mem [IMG_MEM_SIZE];
static struct _IplImage *image_ref;
static struct CvMemStorage *storage;
static struct CvSeq *contours;
+static int contours_n;
static struct CvBox2D rectangle;
/******************************************************************************
******* static functions *****************************************************
******************************************************************************/
- /* Actions */
-static void img_iface_action (int action, void *data);
/* img_cv */
static void img_iface_invert (void);
static void img_iface_bgr2gray (void);
@@ -74,6 +73,7 @@ static void img_iface_adaptive_thr (void *data);
static void img_iface_dilate (void *data);
static void img_iface_erode (void *data);
static void img_iface_contours (void *data);
+static void img_iface_contours_size (void *data);
static void img_iface_min_area_rect (void *data);
static void img_iface_rotate_orto (void *data);
static void img_iface_rotate (void *data);
@@ -146,23 +146,7 @@ void img_iface_cleanup (void)
cvReleaseImage(&image_copy_usr);
}
-struct _IplImage *img_iface_act (int action, void *data)
-{
- img_iface_action(action, data);
-
- /* Make a static copy of tmp so that it isn't modified by the user */
- cvReleaseImage(&image_copy_usr);
- image_copy_usr = cvCloneImage(image_copy_tmp);
-
- return image_copy_usr;
-}
-
-
-/******************************************************************************
- ******* static functions *****************************************************
- ******************************************************************************/
-/* Actions -------------------------------------------------------------------*/
-static void img_iface_action (int action, void *data)
+void img_iface_act (int action, void *data)
{
switch (action) {
/* img_cv */
@@ -193,6 +177,9 @@ static void img_iface_action (int action, void *data)
case IMG_IFACE_ACT_CONTOURS:
img_iface_contours(data);
break;
+ case IMG_IFACE_ACT_CONTOURS_SIZE:
+ img_iface_contours_size(data);
+ break;
case IMG_IFACE_ACT_MIN_AREA_RECT:
img_iface_min_area_rect(data);
break;
@@ -265,6 +252,19 @@ static void img_iface_action (int action, void *data)
}
}
+struct _IplImage *img_iface_show (void)
+{
+ /* Make a static copy of tmp so that it isn't modified by the user */
+ cvReleaseImage(&image_copy_usr);
+ image_copy_usr = cvCloneImage(image_copy_tmp);
+
+ return image_copy_usr;
+}
+
+
+/******************************************************************************
+ ******* static functions *****************************************************
+ ******************************************************************************/
/* img_cv --------------------------------------------------------------------*/
static void img_iface_invert (void)
{
@@ -520,6 +520,17 @@ static void img_iface_erode (void *data)
static void img_iface_contours (void *data)
{
+ /* Must have 1 channel */
+ if (image_copy_tmp->nChannels != 1) {
+ /* Write into log */
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "! Invalid input");
+ user_iface_log.lvl[user_iface_log.len] = 0;
+ (user_iface_log.len)++;
+
+ return;
+ }
+
/* Data */
struct Img_Iface_Data_Contours data_tmp;
if (!data) {
@@ -529,17 +540,57 @@ static void img_iface_contours (void *data)
data_tmp.contours = &contours;
*(data_tmp.contours) = NULL;
+ data_tmp.n = &contours_n;
+
data = (void *)&data_tmp;
}
+ /* Contours */
+ img_cv_act(&image_copy_tmp, IMG_CV_ACT_CONTOURS, data);
+
/* Write into log */
+ struct Img_Iface_Data_Contours *data_cast;
+ data_cast = (struct Img_Iface_Data_Contours *)data;
snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Contours");
+ "Contours n=%i",
+ *(data_cast->n));
user_iface_log.lvl[user_iface_log.len] = 1;
(user_iface_log.len)++;
+}
+
+static void img_iface_contours_size (void *data)
+{
+ /* Data */
+ struct Img_Iface_Data_Contours_Size data_tmp;
+ if (!data) {
+ data_tmp.contours = contours;
+
+ data_tmp.n = contours_n;
+
+ data = (void *)&data_tmp;
+ }
/* Contours */
- img_cv_act(&image_copy_tmp, IMG_CV_ACT_CONTOURS, data);
+ img_cv_act(&image_copy_tmp, IMG_CV_ACT_CONTOURS_SIZE, data);
+
+ /* Write into log */
+ struct Img_Iface_Data_Contours_Size *data_cast;
+ data_cast = (struct Img_Iface_Data_Contours_Size *)data;
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Contours size:",
+ data_cast->n);
+ user_iface_log.lvl[user_iface_log.len] = 1;
+ (user_iface_log.len)++;
+ int i;
+ for (i = 0; i < data_cast->n; i++) {
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "cnt[%i]: A=%lf; P=%lf;",
+ i,
+ data_cast->area[i],
+ data_cast->perimeter[i]);
+ user_iface_log.lvl[user_iface_log.len] = 2;
+ (user_iface_log.len)++;
+ }
}
static void img_iface_min_area_rect (void *data)
@@ -547,7 +598,7 @@ static void img_iface_min_area_rect (void *data)
/* Data */
struct Img_Iface_Data_MinARect data_tmp;
if (!data) {
- data_tmp.contours = &contours;
+ data_tmp.contours = contours;
data_tmp.rect = &rectangle;
diff --git a/modules/image/src/img_orb.cpp b/modules/image/src/img_orb.cpp
index cbb4d68..8efe136 100644
--- a/modules/image/src/img_orb.cpp
+++ b/modules/image/src/img_orb.cpp
@@ -106,7 +106,7 @@ static void img_orb_align (struct _IplImage *img_ref,
/* Extract location of good matches */
std::vector <class cv::Point_ <float>> points_0;
std::vector <class cv::Point_ <float>> points_1;
- int i;
+ int i;
for (i = 0; i < matches.size(); i++) {
points_1.push_back(keypoints_1[matches[i].queryIdx].pt);
points_0.push_back(keypoints_0[matches[i].trainIdx].pt);
diff --git a/modules/proc/inc/proc.h b/modules/proc/inc/proc.h
index 70a5534..132df3e 100644
--- a/modules/proc/inc/proc.h
+++ b/modules/proc/inc/proc.h
@@ -46,7 +46,7 @@
/******************************************************************************
******* functions ************************************************************
******************************************************************************/
-bool proc_iface (int proc_mode);
+int proc_iface (int proc_mode);
/******************************************************************************
diff --git a/modules/proc/src/proc.c b/modules/proc/src/proc.c
index f9c2c43..0858aa3 100644
--- a/modules/proc/src/proc.c
+++ b/modules/proc/src/proc.c
@@ -6,6 +6,13 @@
/******************************************************************************
******* headers **************************************************************
******************************************************************************/
+
+/* Packages ------------------------------------------------------------------*/
+ /* opencv */
+ #include <cv.h>
+ #include <highgui.h>
+ /* ZBAR_EAN13 */
+ #include <zbar.h>
/* * * * * * * * * *
* * * Standard * * * * * *
* * * * * * * * * */
@@ -34,304 +41,405 @@
/******************************************************************************
******* macros ***************************************************************
******************************************************************************/
+ # define OK (0)
+ # define NOK_LABEL (1)
+ # define NOK_CERDO (2)
+ # define NOK_BCODE (3)
+ # define NOK_PRODUCT (4)
+ # define NOK_PRICE (5)
+
+ # define show (false)
+ # define pause (false)
/******************************************************************************
******* variables ************************************************************
******************************************************************************/
+static struct _IplImage *imgptr;
+static struct CvMemStorage *proc_storage;
/******************************************************************************
******* static functions *****************************************************
******************************************************************************/
-static bool proc_etiqueta (void);
+static int proc_etiqueta (void);
+static void result_etiqueta (int status);
+
+static void proc_save_mem (int n);
+static void proc_load_mem (int n);
+static void proc_cmp (int cmp);
+static void proc_smooth (int method, int mask_size);
+static void proc_adaptive_threshold (int method, int type, int size);
+static void proc_threshold (int type, int size);
+static void proc_invert (void);
+static void proc_dilate_erode (int size);
+static void proc_contours (struct CvSeq **cont, int *n);
+static void proc_min_area_rect (struct CvSeq *cont,
+ struct CvBox2D *rect);
+static void proc_rotate (struct CvBox2D *rect);
+static void proc_ROI (int x, int y, int w, int h);
+static void proc_crop (void);
+static void proc_OCR (int lang, int conf);
+static void proc_zbar (int type);
+
+static void proc_show_img (void);
/******************************************************************************
******* main *****************************************************************
******************************************************************************/
-bool proc_iface (int proc_mode)
+int proc_iface (int proc_mode)
{
+ int error;
+
switch (proc_mode) {
case PROC_MODE_ETIQUETA:
- proc_etiqueta();
+ error = proc_etiqueta();
break;
}
- return false;
+ return error;
}
/******************************************************************************
******* static functions *****************************************************
******************************************************************************/
-static bool proc_etiqueta (void)
+static int proc_etiqueta (void)
{
- struct _IplImage *imgptr;
-
- bool label;
- bool product;
- bool price;
-
-// getchar();
- /*
- * A: Save to mem_0
- * First, find the label, then return to this image and rotate it to
- * straight position (to help OCR).
- */
- int data_A;
- data_A = 0;
- imgptr = img_iface_act(IMG_IFACE_ACT_SAVE_MEM, (void *)&data_A);
- /* Display image and do NOT wait for any key to continue */
- cvShowImage(WIN_NAME, imgptr);
- cvWaitKey(WIN_TIMEOUT);
+ int status;
+
+ char price [6];
+
+ struct CvSeq *et_contours;
+ int et_contours_n;
+ struct CvBox2D et_rect;
+ int x;
+ int y;
+ int w;
+ int h;
+
+ proc_storage = cvCreateMemStorage(0);
+
+ proc_save_mem(0);
+ /* Find label (position and angle) */
+ {
+ proc_cmp(IMG_IFACE_CMP_BLUE);
+ proc_smooth(CV_MEDIAN, 7);
+ #if 0
+ proc_adaptive_threshold(CV_ADAPTIVE_THRESH_MEAN_C,
+ CV_THRESH_BINARY, 5);
+ #else
+ proc_invert();
+ #endif
+ proc_smooth(CV_BLUR, 21);
+ proc_threshold(CV_THRESH_BINARY_INV, 2);
+ proc_dilate_erode(100);
+ proc_contours(&et_contours, &et_contours_n);
+
+ /* If no contour is found, error: NOK_LABEL */
+ if (!et_contours) {
+ status = NOK_LABEL;
+ result_etiqueta(status);
+ return status;
+ }
+
+ proc_min_area_rect(et_contours, &et_rect);
+
+ /* If angle is < -45º, it is taking into acount the incorrect side */
+ if (et_rect.angle < -45.0) {
+ int tmp;
+ et_rect.angle = et_rect.angle + 90.0;
+ tmp = et_rect.size.width;
+ et_rect.size.width = et_rect.size.height;
+ et_rect.size.height = tmp;
+ }
+ }
+ /* Align label and extract green component */
+ {
+ proc_load_mem(0);
+ proc_rotate(&et_rect);
+ proc_cmp(IMG_IFACE_CMP_GREEN);
+ proc_save_mem(1);
+ }
+ /* Find "Cerdo" in aligned image */
+ {
+
+ x = et_rect.center.x - (1.05 * et_rect.size.width / 2);
+ y = et_rect.center.y - (1.47 * et_rect.size.height / 2);
+ w = et_rect.size.width / 2;
+ h = et_rect.size.height * 0.20;
+ proc_ROI(x, y, w, h);
+ proc_crop();
+ proc_threshold(CV_THRESH_BINARY, IMG_IFACE_THR_OTSU);
+ proc_OCR(IMG_IFACE_OCR_LANG_SPA, 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 = NOK_CERDO;
+ result_etiqueta(status);
+ return status;
+ }
+ }
+ /* Read barcode in original image */
+ {
+ proc_load_mem(0);
+ proc_cmp(IMG_IFACE_CMP_GREEN);
+ proc_zbar(ZBAR_EAN13);
+
+ /* Check that 1 and only 1 bcode is read. */
+ if (zb_codes.n != 1) {
+ status = NOK_BCODE;
+ result_etiqueta(status);
+ return status;
+ }
+ }
+ /* Check product code in barcode */
+ {
+ bool prod_nok;
+ prod_nok = strncmp(zb_codes.arr[0].data, "2301703",
+ strlen("2301703"));
+ if (prod_nok) {
+ status = NOK_PRODUCT;
+ result_etiqueta(status);
+ return status;
+ }
+ }
+ /* Read price in aligned image (green component) */
+ {
+ proc_load_mem(1);
+
+ x = et_rect.center.x + (0.33 * et_rect.size.width / 2);
+ y = et_rect.center.y + (0.64 * et_rect.size.height / 2);
+ w = et_rect.size.width * 0.33;
+ h = et_rect.size.height * 0.15;
+ proc_ROI(x, y, w, h);
+ proc_crop();
+ proc_smooth(CV_BLUR, 3);
+ proc_threshold(CV_THRESH_BINARY, IMG_IFACE_THR_OTSU);
+// proc_threshold(CV_THRESH_BINARY, 100);
+// proc_smooth(CV_BLUR, 3);
+ proc_OCR(IMG_IFACE_OCR_LANG_ENG, IMG_IFACE_OCR_CONF_PRICE);
+ }
+ /* Extract price from barcode */
+ {
+ if (zb_codes.arr[0].data[8] != '0') {
+ snprintf(price, 6, "%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, 6, "%c.%c%c€",
+ zb_codes.arr[0].data[9],
+ zb_codes.arr[0].data[10],
+ zb_codes.arr[0].data[11]);
+ }
+ }
+ /* Check label price with barcode price */
+ {
+ bool price_nok;
+ price_nok = strncmp(img_ocr_text, price, strlen(price));
+ if (price_nok) {
+ status = NOK_PRICE;
+ result_etiqueta(status);
+ return status;
+ }
+ }
- /*
- * B: Extract green cmp
- * Because of the type of light used, green is the best component.
- */
- struct Img_Iface_Data_Component data_B;
- data_B.cmp = 0; /* B=0, G=1, R=2 */
- imgptr = img_iface_act(IMG_IFACE_ACT_COMPONENT, (void *)&data_B);
- /* Display image and do NOT wait for any key to continue */
- cvShowImage(WIN_NAME, imgptr);
- cvWaitKey(WIN_TIMEOUT);
+ status = OK;
+ result_etiqueta(status);
+ return status;
+}
-// getchar();
- /*
- * D: Smooth (median 3x3)
- * Median filter to remove salt noise.
- */
- struct Img_Iface_Data_Smooth data_C;
- data_C.method = CV_MEDIAN;
- data_C.msk_siz = 7;
- imgptr = img_iface_act(IMG_IFACE_ACT_SMOOTH, (void *)&data_C);
- /* Display image and do NOT wait for any key to continue */
- cvShowImage(WIN_NAME, imgptr);
- cvWaitKey(WIN_TIMEOUT);
+static void result_etiqueta (int status)
+{
+ /* Cleanup */
+ cvReleaseMemStorage(&proc_storage);
+
+ /* Write result into log */
+ char result [LOG_LINE_LEN];
+ switch (status) {
+ case OK:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Label: OK");
+ break;
+ case NOK_LABEL:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Label: NOK_LABEL");
+ break;
+ case NOK_CERDO:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Label: NOK_CERDO");
+ break;
+ case NOK_BCODE:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Label: NOK_BCODE");
+ break;
+ case NOK_PRODUCT:
+ snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
+ "Label: NOK_PRODUCT");
+ break;
+ case 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] = 1;
+ (user_iface_log.len)++;
+}
- /*
- * C: Detect label.
- * If value is 0, it will detect plain surfaces.
- * It causes problems when there is much noise.
- * If set to 1, it will detect white surfaces.
- */
-// getchar();
-#if 0
- struct Img_Iface_Data_Adaptive_Thr data_D;
- data_D.method = CV_ADAPTIVE_THRESH_MEAN_C;
- data_D.thr_typ = CV_THRESH_BINARY;
- data_D.nbh_val = 5;
- imgptr = img_iface_act(USER_IFACE_ACT_ADAPTIVE_THRESHOLD, (void *)&data_D);
- /* Display image and do NOT wait for any key to continue */
- cvShowImage(WIN_NAME, imgptr);
- cvWaitKey(WIN_TIMEOUT);
-#else
- imgptr = img_iface_act(USER_IFACE_ACT_INVERT, NULL);
- /* Display image and do NOT wait for any key to continue */
- cvShowImage(WIN_NAME, imgptr);
- cvWaitKey(WIN_TIMEOUT);
-#endif
-
-// getchar();
- /*
- * D: Smooth (mean 15x15)
- * Fast smooth to homogenize the label in black,
- * and noise in gray.
- */
- struct Img_Iface_Data_Smooth data_E;
- data_E.method = CV_BLUR;
- data_E.msk_siz = 21;
- imgptr = img_iface_act(IMG_IFACE_ACT_SMOOTH, (void *)&data_E);
- /* Display image and do NOT wait for any key to continue */
- cvShowImage(WIN_NAME, imgptr);
- cvWaitKey(WIN_TIMEOUT);
+static void proc_save_mem (int n)
+{
+ img_iface_act(IMG_IFACE_ACT_SAVE_MEM, (void *)&n);
+}
-// getchar();
- /*
- * E: Threshold (BIN_INV)
- * Label will be white; rest in black.
- */
- struct Img_Iface_Data_Threshold data_F;
- data_F.thr_typ = CV_THRESH_BINARY_INV;
- data_F.thr_val = 2;
- imgptr = img_iface_act(IMG_IFACE_ACT_THRESHOLD, (void *)&data_F);
- /* Display image and do NOT wait for any key to continue */
- cvShowImage(WIN_NAME, imgptr);
- cvWaitKey(WIN_TIMEOUT);
+static void proc_load_mem (int n)
+{
+ img_iface_act(IMG_IFACE_ACT_LOAD_MEM, (void *)&n);
-// getchar();
- /*
- * F: Dilate-erode (100 times)
- * Join all white blobs into one single blob.
- */
- struct Img_Iface_Data_Dilate_Erode data_G;
- data_G.i = 100;
- imgptr = img_iface_act(IMG_IFACE_ACT_DILATE_ERODE, (void *)&data_G);
- /* Display image and do NOT wait for any key to continue */
- cvShowImage(WIN_NAME, imgptr);
- cvWaitKey(WIN_TIMEOUT);
+ proc_show_img();
+}
-// getchar();
- /*
- * G: Find contour
- * This is neccessary for the next step.
- */
- struct CvMemStorage *et_storage;
- struct CvSeq *et_contours;
- struct Img_Iface_Data_Contours data_H;
- et_storage = cvCreateMemStorage(0);
- data_H.storage = &et_storage;
- data_H.contours = &et_contours;
- imgptr = img_iface_act(IMG_IFACE_ACT_CONTOURS, (void *)&data_H);
- /* Display image and do NOT wait for any key to continue */
- cvShowImage(WIN_NAME, imgptr);
- cvWaitKey(WIN_TIMEOUT);
+static void proc_cmp (int cmp)
+{
+ struct Img_Iface_Data_Component data;
+ data.cmp = cmp;
+ img_iface_act(IMG_IFACE_ACT_COMPONENT, (void *)&data);
- /* If no contour is found, label is NOK */
- if (!et_contours) {
- label = false;
- return label;
- }
+ proc_show_img();
+}
-// getchar();
- /*
- * H: Find minimum area rectangle for the contours found
- * This rectangle will contain the label (the white part of it).
- */
- struct CvBox2D et_rect_minA;
- struct Img_Iface_Data_MinARect data_I;
- data_I.contours = &et_contours;
- data_I.rect = &et_rect_minA;
- imgptr = img_iface_act(IMG_IFACE_ACT_MIN_AREA_RECT, (void *)&data_I);
- /* Display image and do NOT wait for any key to continue */
- cvShowImage(WIN_NAME, imgptr);
- cvWaitKey(WIN_TIMEOUT);
+static void proc_smooth (int method, int mask_size)
+{
+ struct Img_Iface_Data_Smooth data;
+ data.method = method;
+ data.msk_siz = mask_size;
+ img_iface_act(IMG_IFACE_ACT_SMOOTH, (void *)&data);
- /* If angle is < -45º, it is taking into acount the incorrect side */
- if (et_rect_minA.angle < -45.0) {
- int tmp;
- et_rect_minA.angle = et_rect_minA.angle + 90.0;
- tmp = et_rect_minA.size.width;
- et_rect_minA.size.width = et_rect_minA.size.height;
- et_rect_minA.size.height = tmp;
- }
+ proc_show_img();
+}
-// getchar();
- /*
- * I: Load image from mem_0
- * Recover the image stored previously, which will be rotated with
- * the information gained with the rectangle (position, size & angle).
- */
- int data_J;
- data_J = 0;
- imgptr = img_iface_act(IMG_IFACE_ACT_LOAD_MEM, (void *)&data_J);
- /* Display image and do NOT wait for any key to continue */
- cvShowImage(WIN_NAME, imgptr);
- cvWaitKey(WIN_TIMEOUT);
+static void proc_adaptive_threshold (int method, int type, int size)
+{
+ struct Img_Iface_Data_Adaptive_Thr data;
+ data.method = method;
+ data.thr_typ = type;
+ data.nbh_val = size;
+ img_iface_act(USER_IFACE_ACT_ADAPTIVE_THRESHOLD, (void *)&data);
- /*
- * K: Extract green cmp
- * Because of the type of light used, green is the best component.
- */
- struct Img_Iface_Data_Component data_K;
- data_K.cmp = 1; /* B=0, G=1, R=2 */
- imgptr = img_iface_act(IMG_IFACE_ACT_COMPONENT, (void *)&data_K);
- /* Display image and do NOT wait for any key to continue */
- cvShowImage(WIN_NAME, imgptr);
- cvWaitKey(WIN_TIMEOUT);
+ proc_show_img();
+}
-// getchar();
- /*
- * J: Rotate
- * Align the label.
- */
- struct Img_Iface_Data_Rotate data_L;
- data_L.center.x = et_rect_minA.center.x;
- data_L.center.y = et_rect_minA.center.y;
- data_L.angle = et_rect_minA.angle;
- imgptr = img_iface_act(IMG_IFACE_ACT_ROTATE, (void *)&data_L);
- /* Display image and do NOT wait for any key to continue */
- cvShowImage(WIN_NAME, imgptr);
- cvWaitKey(WIN_TIMEOUT);
+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);
-// getchar();
- /*
- * K: Save to mem_1
- * Save the aligned image, from which several ROIs will be extracted.
- */
- int data_M;
- data_M = 1;
- imgptr = img_iface_act(IMG_IFACE_ACT_SAVE_MEM, (void *)&data_M);
- /* Display image and do NOT wait for any key to continue */
- cvShowImage(WIN_NAME, imgptr);
- cvWaitKey(WIN_TIMEOUT);
+ proc_show_img();
+}
-// getchar();
- /*
- * L: Set ROI: Cerdo
- * Set a ROI that contains "Cerdo".
- */
- struct Img_Iface_Data_SetROI data_N;
- data_N.rect.x = et_rect_minA.center.x -
- (1.05 * et_rect_minA.size.width / 2);
- data_N.rect.y = et_rect_minA.center.y -
- (1.47 * et_rect_minA.size.height / 2);
- data_N.rect.width = et_rect_minA.size.width / 2;
- data_N.rect.height = et_rect_minA.size.height * 0.20;
- imgptr = img_iface_act(IMG_IFACE_ACT_SET_ROI, (void *)&data_N);
- /* Display image and do NOT wait for any key to continue */
- cvShowImage(WIN_NAME, imgptr);
- cvWaitKey(WIN_TIMEOUT);
+static void proc_invert (void)
+{
+ img_iface_act(USER_IFACE_ACT_INVERT, NULL);
-// getchar();
- /*
- * M: Crop to ROI Cerdo
- */
- imgptr = img_iface_act(IMG_IFACE_ACT_CROP, NULL);
- /* Display image and do NOT wait for any key to continue */
- cvShowImage(WIN_NAME, imgptr);
- cvWaitKey(WIN_TIMEOUT);
+ proc_show_img();
+}
-// getchar();
- /*
- * N: Threshold (BIN)
- * "Cerdo" will be white; rest in black.
- */
- struct Img_Iface_Data_Threshold data_O;
- data_O.thr_typ = CV_THRESH_BINARY;
- data_O.thr_val = -1;
- imgptr = img_iface_act(IMG_IFACE_ACT_THRESHOLD, (void *)&data_O);
- /* Display image and do NOT wait for any key to continue */
- cvShowImage(WIN_NAME, imgptr);
- cvWaitKey(WIN_TIMEOUT);
+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);
-// getchar();
- /*
- * O: OCR
- * OCR text should be: "Cerdo"
- */
- struct Img_Iface_Data_Read data_P;
- data_P.lang = 1; /* eng=0, spa=1, cat=2 */
- data_P.conf = 0; /* none=0, price=1 */
- imgptr = img_iface_act(IMG_IFACE_ACT_READ, (void *)&data_P);
- /* Display image and do NOT wait for any key to continue */
- cvShowImage(WIN_NAME, imgptr);
- cvWaitKey(WIN_TIMEOUT);
- label = strncmp(img_ocr_text, "Cerdo", 5);
- /* Write into log */
- snprintf(user_iface_log.line[user_iface_log.len], LOG_LINE_LEN,
- "Label: %i", label);
- user_iface_log.lvl[user_iface_log.len] = 1;
- (user_iface_log.len)++;
+ proc_show_img();
+}
-// getchar();
- /* Cleanup */
- cvReleaseMemStorage(&et_storage);
+static void proc_contours (struct CvSeq **cont, int *n)
+{
+ struct Img_Iface_Data_Contours data;
+ data.storage = &proc_storage;
+ data.contours = cont;
+ data.n = n;
+ img_iface_act(IMG_IFACE_ACT_CONTOURS, (void *)&data);
+
+ proc_show_img();
+}
+
+static void proc_min_area_rect (struct CvSeq *cont,
+ struct CvBox2D *rect)
+{
+ struct Img_Iface_Data_MinARect data;
+ data.contours = cont;
+ data.rect = rect;
+ img_iface_act(IMG_IFACE_ACT_MIN_AREA_RECT, (void *)&data);
+ proc_show_img();
+}
+
+static void proc_rotate (struct CvBox2D *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_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);
+}
-// getchar();
- return false;
+static void proc_crop (void)
+{
+ img_iface_act(IMG_IFACE_ACT_CROP, NULL);
+
+ 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 = type;
+ img_iface_act(IMG_IFACE_ACT_DECODE, (void *)&data);
+}
+
+static void proc_show_img (void)
+{
+ if (show) {
+ imgptr = img_iface_show();
+ /* Display image and do NOT wait for any key to continue */
+ cvShowImage(WIN_NAME, imgptr);
+ cvWaitKey(WIN_TIMEOUT);
+ }
+ if (pause) {
+ getchar();
+ }
}
diff --git a/modules/user/inc/user_iface.h b/modules/user/inc/user_iface.h
index b0bd17a..5b26705 100644
--- a/modules/user/inc/user_iface.h
+++ b/modules/user/inc/user_iface.h
@@ -48,6 +48,7 @@
USER_IFACE_ACT_DILATE,
USER_IFACE_ACT_ERODE,
USER_IFACE_ACT_CONTOURS,
+ USER_IFACE_ACT_CONTOURS_SIZE,
USER_IFACE_ACT_MIN_AREA_RECT,
USER_IFACE_ACT_ROTATE_ORTO,
USER_IFACE_ACT_ROTATE,
diff --git a/modules/user/inc/user_iface.hpp b/modules/user/inc/user_iface.hpp
index a12ba49..6d290d6 100644
--- a/modules/user/inc/user_iface.hpp
+++ b/modules/user/inc/user_iface.hpp
@@ -55,6 +55,7 @@ extern "C" {
USER_IFACE_ACT_DILATE,
USER_IFACE_ACT_ERODE,
USER_IFACE_ACT_CONTOURS,
+ USER_IFACE_ACT_CONTOURS_SIZE,
USER_IFACE_ACT_MIN_AREA_RECT,
USER_IFACE_ACT_ROTATE_ORTO,
USER_IFACE_ACT_ROTATE,
diff --git a/modules/user/src/user_iface.c b/modules/user/src/user_iface.c
index 7a7f20d..da8fe98 100644
--- a/modules/user/src/user_iface.c
+++ b/modules/user/src/user_iface.c
@@ -118,9 +118,11 @@ void user_iface (struct _IplImage *imgptr)
proc_iface(user_action);
break;
default:
- imgptr = user_iface_act(user_action);
+ user_iface_act(user_action);
break;
}
+
+ imgptr = img_iface_show();
} while (user_action != USER_IFACE_ACT_QUIT);
}
@@ -195,7 +197,7 @@ struct _IplImage *user_iface_act (int action)
break;
}
} else {
- imgptr = img_iface_act(action, NULL);
+ img_iface_act(action, NULL);
}
return imgptr;
diff --git a/modules/user/src/user_tui.c b/modules/user/src/user_tui.c
index 881a708..9321da1 100644
--- a/modules/user/src/user_tui.c
+++ b/modules/user/src/user_tui.c
@@ -176,7 +176,7 @@ static void log_loop (void)
int l;
int l_0;
- if ((user_iface_log.len - 21) > 0) {
+ if ((user_iface_log.len - 40) > 0) {
i_0 = user_iface_log.len - 21;
l_0 = 1;
mvwprintw(win_log, 1, 10, "...");
@@ -311,6 +311,9 @@ static int usr_input (void)
action = USER_IFACE_ACT_CONTOURS;
break;
case '1':
+ action = USER_IFACE_ACT_CONTOURS_SIZE;
+ break;
+ case '2':
action = USER_IFACE_ACT_MIN_AREA_RECT;
break;
default:
@@ -498,7 +501,8 @@ static void show_help (void)
mvwprintw(win_help, r++, c, " - D-E: %s", "f122");
mvwprintw(win_help, r++, c, " - E-D: %s", "f123");
mvwprintw(win_help, r++, c, " - Contours: %s", "f130");
- mvwprintw(win_help, r++, c, " - Min. A rect.:%s", "f131");
+ mvwprintw(win_help, r++, c, " - Contours siz:%s", "f131");
+ mvwprintw(win_help, r++, c, " - Min. A rect.:%s", "f132");
mvwprintw(win_help, r++, c, " - Rotate orto.:%s", "f140");
mvwprintw(win_help, r++, c, " - Rotate: %s", "f141");
mvwprintw(win_help, r++, c, " - Rotate 2rect:%s", "f142");