Проблемы с использованием OpenCV с ZBar в C

Я пытаюсь использовать OpenCV для загрузки изображения jpg из файла и передачи его в библиотеку zbar для декодирования штрих-кода. Однако никакие штрих-коды не декодируются должным образом, хотя приведенный ниже код работает, когда я использую функции из libpng для загрузки изображения. У меня нет ошибок, и я понятия не имею, в чем проблема, так как я уже проверил все сообщения, которые смог найти, и ничего не помогло.

Заранее спасибо.

#include <stdio.h>
#include <stdlib.h>
#include <zbar.h>
#include <cv.h>
#include <highgui.h>
#include <math.h>


zbar_image_scanner_t *scanner = NULL;
IplImage* cvLoadImage(const char* filename, int iscolor);

int main (int argc, char **argv)
{

    // create a reader
    scanner = zbar_image_scanner_create();

    // configure the reader
    zbar_image_scanner_set_config(scanner, 0, ZBAR_CFG_ENABLE, 1);

    // obtain image data with opencv
    IplImage* img = 0;
    int height,width,step,channels;
    img = cvLoadImage(argv[1], 1);
    height = img->height;
    width = img->width;
    step = img->widthStep;
    channels = img->nChannels;
    void *raw = (void *)(img->imageData);
    printf("Processing a %dx%d image \n",height,width);

    // wrap image data
    zbar_image_t *image = zbar_image_create();
    zbar_image_set_format(image, *(int*)"Y800");
    zbar_image_set_size(image, width, height);
    zbar_image_set_data(image, raw, width * height, zbar_image_free_data);


    // scan the image for barcodes
    int n = zbar_scan_image(scanner, image);

    if (n==0){
        printf("No barcode detected for image %s\n", argv[1]);
        return 1;
    }

    // extract results
    if (n!=0) {
        const zbar_symbol_t *symbol = zbar_image_first_symbol(image);
        printf("symbol extracted \n");
        for(; symbol; symbol = zbar_symbol_next(symbol)) {
            // do something useful with results
            zbar_symbol_type_t typ = zbar_symbol_get_type(symbol);
            const char *dataZ = zbar_symbol_get_data(symbol);
            printf("decoded %s symbol \"%s\" of image %s \n", zbar_get_symbol_name(typ), dataZ, argv[1]);
        }
    }

    // clean up
    zbar_image_destroy(image);
    zbar_image_scanner_destroy(scanner);

return 0;
}

person Frc14    schedule 05.06.2017    source источник


Ответы (1)


Этот код отлично сработал для меня. Я использовал его в своей программе с небольшими изменениями:

Я не показываю, как я получаю 'struct _IplImage *' {aka 'IplImage *'}, потому что это делается в другом файле и получает его как параметр, но, конечно же, это делается с cvLoadImage().

Я использовал "GREY" вместо "Y800", но попробовал "Y800" и тоже сработало, так как они принципиально одинаковы.

Это работает (по крайней мере, с openCV 2.4.9; openCV отказывается от своего C API, и вместо этого следует использовать его C++ API (я против этого, но ничего не поделаешь :()):

/******************************************************************************
 ******* headers **************************************************************
 ******************************************************************************/
/* Standard C ----------------------------------------------------------------*/
        /* snprintf() */
    #include <stdio.h>

/* Packages ------------------------------------------------------------------*/
        /* opencv */
    #include <cv.h>
        /* zbar */
    #include <zbar.h>

/* Module --------------------------------------------------------------------*/
    #include "this_file.h"


/******************************************************************************
 ******* macros ***************************************************************
 ******************************************************************************/
    # define    ZB_CODES_MAX        (10)
    # define    ZBAR_LEN_MAX        (1048576)


/******************************************************************************
 ******* structs **************************************************************
 ******************************************************************************/
    struct  ZB_Codes {
        int n;
        struct {
            int type;
            char    sym_name [80];
            char    data [ZBAR_LEN_MAX];
        } arr [ZB_CODES_MAX];
    };


/******************************************************************************
 ******* variables ************************************************************
 ******************************************************************************/
    struct ZB_Codes zb_codes;


/******************************************************************************
 ******* functions ************************************************************
 ******************************************************************************/
void    img_zb_decode   (struct _IplImage *imgptr)
{
    struct zbar_image_scanner_s *scanner;
    struct zbar_image_s     *image_zb;
    const struct zbar_symbol_s  *symbol;

    /* Type of code to scan */
    /* 0 for all;  set to another if used only for a specific barcode */
    int code_type;
    code_type   = 0;

    /* create & configure a reader */
    scanner = zbar_image_scanner_create();
    zbar_image_scanner_set_config(scanner, code_type, ZBAR_CFG_ENABLE, 1);

    /* wrap image data */
    image_zb    = zbar_image_create();
    zbar_image_set_format(image_zb, *(int *)"GREY");
    zbar_image_set_size(image_zb, imgptr->width, imgptr->height);
    zbar_image_set_data(image_zb, (void *)(imgptr->imageData),
                    (imgptr->width * imgptr->height), NULL);

    /* scan the image for barcodes */
    int i;
    zb_codes.n  = zbar_scan_image(scanner, image_zb);
    if (zb_codes.n) {
        /* extract results */
        symbol  = zbar_image_first_symbol(image_zb);
        for (i = 0; i < ZB_CODES_MAX && symbol; i++) {
            /* Write results into array */
            zb_codes.arr[i].type    = zbar_symbol_get_type(symbol);
            snprintf(zb_codes.arr[i].sym_name, 80, "%s",
                        zbar_get_symbol_name(
                            zb_codes.arr[i].type));
            snprintf(zb_codes.arr[i].data, ZBAR_LEN_MAX, "%s",
                        zbar_symbol_get_data(symbol));

            /* Load next symbol */
            symbol  = zbar_symbol_next(symbol);
        }
    }

    /* clean up */
    zbar_image_destroy(image_zb);
    zbar_image_scanner_destroy(scanner);
}


/******************************************************************************
 ******* end of file **********************************************************
 ******************************************************************************/
person alx    schedule 19.10.2018
comment
Если вам все еще нужно, как я получил struct _IplImage *imgptr, пожалуйста, скажите мне. - person alx; 19.10.2018