ZXing (пересечение зебры) на C#

Я ищу хорошую библиотеку с открытым исходным кодом, которая может найти и прочитать штрих-код с изображения (по сравнению с использованием сканера штрих-кода). Из других вопросов о переполнении стека я обнаружил, что ZXing ("Пересечение зебры") достаточно хорошо. Хотя он сделан для Java, есть порт C#, однако я считаю, что он может быть неполным. Как вы думаете, достаточно ли надежно разобрать штрих-код в такой ситуации, или какая-то другая библиотека лучше?

РЕДАКТИРОВАТЬ: Как указал Эд в комментариях, я должен сначала попробовать. Вау, я не подумал об этом. :) но я думаю, что мой вопрос в том, достаточно ли надежен частичный порт - если кто-то из вас использовал его раньше, может ли он сканировать со знанием дела?


person Maxim Zaslavsky    schedule 28.10.2009    source источник
comment
Почему бы тебе просто, знаешь... не попробовать?   -  person Ed S.    schedule 29.10.2009
comment
@Эд О, эм, ага! Ха-ха, вы знаете, я думаю, мне нужно закрыть свой вопрос. Опси.   -  person Maxim Zaslavsky    schedule 29.10.2009
comment
Ну а сам вопрос будет полезен людям в будущем, так что не думаю, что правильно его закрывать. Кроме того, у некоторых людей могут быть идеи, на изучение которых требуется время, которые вы можете упустить с первого взгляда. Я просто предположил, что в то же время попробовать это будет моей первой целью.   -  person Ed S.    schedule 29.10.2009
comment
Да, полностью согласен, спасибо! Я собираюсь попробовать это как можно скорее.   -  person Maxim Zaslavsky    schedule 29.10.2009


Ответы (3)


Это, конечно, зависит от того, для чего вы его используете. Даже версия zxing для Java имеет некоторые важные ограничения и проблемы с производительностью. Например, он может найти только один штрих-код на странице. Кроме того, алгоритмы, которые он использует для поиска одномерного штрих-кода на странице, не особенно эффективны (не знаю об алгоритмах для двумерных штрих-кодов - это не входило в требования проекта, над которым я работал). Это все, что можно решить — я начал усовершенствование несколько месяцев назад и смог значительно улучшить производительность и надежность 1D-локации, но наши приоритеты разработчиков изменились, поэтому с тех пор я не работал над этим.

Что касается того, хорош ли частичный перенос на C #, если вы хотите опубликовать, в чем различия, я был бы рад прокомментировать.

РЕДАКТИРОВАТЬ - вот некоторые из рефакторингов, которые я сделал:

Во-первых, выделим RowNumberStrategy следующим образом:

public interface RowNumberStrategy {
public int getNextRowNumber();

public class OriginalRowStrategy implements RowNumberStrategy{
    int middle;
    boolean tryHarder = false;
    int rowStep;
    int maxLines;
    int maxRows;

    int x;

    public OriginalRowStrategy(int maxRows, boolean tryHarder) {
        this.x = 0;
        this.maxRows = maxRows;
        this.middle = maxRows >> 1; // divide by 2
        this.tryHarder = tryHarder;
        rowStep = Math.max(1, maxRows >> (tryHarder ? 7 : 4));
        if (tryHarder) {
          maxLines = maxRows; // Look at the whole image, not just the center
        } else {
          maxLines = 9; // Nine rows spaced 1/16 apart is roughly the middle half of the image
        }
    }

    public int getNextRowNumber() {
        if (x > maxLines)
            return -1;

        int rowStepsAboveOrBelow = (x + 1) >> 1;
        boolean isAbove = (x & 0x01) == 0; // i.e. is x even?
        int rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow);
        if (rowNumber < 0 || rowNumber >= maxRows) {
          // Oops, if we run off the top or bottom, stop
          return -1;
        }

        x = x + 1;

        return rowNumber;
    }

}

public class LinearScanRowStrategy implements RowNumberStrategy{
    private final int maxRows;
    private int currentRow;
    public LinearScanRowStrategy(int totalRows) {
        maxRows = totalRows;
        currentRow = 0;
    }

    public int getNextRowNumber() {
        if (currentRow > maxRows)
            return -1;

        return maxRows - 1 - currentRow++;
    }

}

public class ProgressiveScanRowStrategy implements RowNumberStrategy{
    private final int maxRows;
    private int currentStepSize;
    private int currentStep;

    public ProgressiveScanRowStrategy(int totalRows) {
        maxRows = totalRows;
        currentStep = 0;
        currentStepSize = maxRows;
    }

    public int getNextRowNumber() {
        int nextRow = (currentStep++) * currentStepSize;
        if (nextRow < maxRows)
            return nextRow;

        currentStepSize = currentStepSize >> 1;
        if (currentStepSize <= 0)
            return -1;
        currentStep = 1;

        nextRow = currentStep * currentStepSize;

        return nextRow;
    }

}



}

тогда верхняя часть doDecode становится следующей:

private Result doDecode(MonochromeBitmapSource image, Hashtable hints) throws ReaderException {


int width = image.getWidth();
int height = image.getHeight();
BitArray row = new BitArray(width);
boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);
RowNumberStrategy rowProvider = new RowNumberStrategy.ProgressiveScanRowStrategy(height);  

int rowNumber;
while ((rowNumber = rowProvider.getNextRowNumber()) != -1){
...
}

в конечном счете, это должно быть что-то, что можно установить с помощью DecodeHintType, но мы обнаружили, что прогрессивная стратегия быстрее, чем старая стратегия, во всех случаях, когда мы могли ее применить (и не просто немного быстрее - намного< /em> быстрее).

person Kevin Day    schedule 29.10.2009
comment
Попробуйте MultipleBarcodeReader для поиска нескольких штрих-кодов на изображении. Не уверен, что вы считаете неэффективным в обнаружении 1D - сканирует пару строк от центра наружу. Во всяком случае, режим по умолчанию быстрый, но поверхностный. - person Sean Owen; 01.11.2009
comment
Я обязательно проверю MBR - спасибо за совет. Алгоритмически стратегия сканирования не работает эффективно для больших изображений (скажем, 3300 строк), поскольку она использует подход с фиксированным шагом. Я отвечу тем, о чем говорю, в полном посте, чтобы показать код. - person Kevin Day; 05.11.2009
comment
Нет, шаг сканирования зависит от высоты — по умолчанию он пропускает высоту/16 строк изображения на каждом шаге. - person Sean Owen; 17.11.2009
comment
Шон – Да, подход с высоты/16 намного медленнее, чем должен быть, и пропускает штрих-коды. Вышеупомянутая адаптивная стратегия работает намного быстрее и позволяет получать штрих-коды всех размеров. Я собираюсь взяться за эту работу еще через месяц или два - я пришлю вам патч. - person Kevin Day; 17.11.2009

Я использую java-версию больше года, сканирую около 100 раз в день, и она отлично работает. Я не вижу причин, по которым версия С# была бы хуже.

person Chris    schedule 29.10.2009

Попробуйте скомпилировать java-версию с помощью ikvmc, чем обращаться к ней из кода C#.

person zvikara    schedule 29.10.2009