Сравнение пикселей двух разных изображений, занимает слишком много времени

#android #image-processing

#Android #обработка изображений

Вопрос:

Я хочу сравнить пиксель двух разных изображений. Я сравниваю пиксель первого изображения со всеми пикселями второго изображения. Вот мой код:

 for (int i = 0; i < bitmap.getWidth(); i  ) {
    for (int j = 0; j < bitmap.getHeight(); j  ) {

        for (int k = 0 ; k<bitmpa2.getWidth(); k  ) {
            for (int l = 0 ; l<bitmpa2.getHeight(); l  ) {

                if (bitmap.getPixel(i, j) == bitmap2.getPixel(k, l))
                  Counter   ;
          }
       }
    }
}
  

Здесь значение Counter — это количество пикселей, которые одинаковы в обоих изображениях. Проблема в том, что это работает, но для его выполнения требуется много времени, поэтому проблема заключается в ограничении времени, поэтому что я могу сделать, чтобы сократить время и получить точный результат. Любая другая возможность приветствуется.

Комментарии:

1. Имеют ли изображения одинаковые размеры и ориентацию?

2. @Ruel да, изображения имеют одинаковый размер.

3. Есть ли какая-либо возможность получить указатель на необработанный растровый буфер в Android? Если это так, вы можете получить ускорение в 32 раза, сравнив 32-разрядные целые числа двух буферов, и только если они отличаются, затем увеличьте масштаб до битовой распаковки, которую выполняет bitmap.GetPixel()? Вам также придется позаботиться о границе, если ширина растрового изображения не является целым числом, кратным 32.

4. @ Dov Grobgeld: я не совсем понимаю вашу точку зрения. не могли бы вы уточнить это?

Ответ №1:

О нет, помните об этом, когда выполняете обработку изображений в Android.

Никогда не используйте GetPixel() или SetPixel() непрерывно, как цикл, это приведет к очень плохой производительности, чертовски медленной. Вместо этого используйте getPixels() и SetPixels()

Что ж, имейте в виду, что сначала вам нужно прочитать документацию по Android.

Ответ №2:

Если вы используете API уровня 12 или выше, есть метод sameAs Bitmap , который выполняет именно то, что вы ищете. В противном случае используйте getPixels и сделайте что-то вроде:

 int width = bitmap1.getWidth();
int height = bitmap1.getHeight();
int pixelCount = width * height;
int[] pixels1 = new int[pixelCount];
int[] pixels2 = new int[pixelCount];

bitmap1.getPixels(pixels1, 0, 0, 0, 0, width, height);
bitmap2.getPixels(pixels2, 0, 0, 0, 0, width, height);

for (int i = 0; i < pixelCount; i  ) {
    if (pixels1[i] != pixels2[i]) {
        return false;
    }
}
return true;
  

Или, если вы действительно хотите использовать счетчик, чтобы увидеть, сколько пикселей одинаковы, продолжайте и сделайте это.

На самом деле, вы, вероятно, тоже можете что-то сделать с буферами… Может быть, что-то вроде

 int width = bitmap1.getWidth();
int height = bitmap1.getHeight();
int pixelCount = width * height;
IntBuffer buffer1 = IntBuffer.allocate(pixelCount);
IntBuffer buffer2 = IntBuffer.allocate(pixelCount);
bitmap1.copyPixelsToBuffer(buffer1);
bitmap2.copyPixelsToBuffer(buffer2);
int result = buffer1.compareTo(buffer2);
  

Я не уверен, как эти два метода сравниваются по производительности, но с этим можно поиграть, если хотите.

Комментарии:

1. Ваши вызовы getPixels завершатся с ошибкой, как написано, шаг должен быть>= width .

2. эй, моя проблема в том, что я хочу сравнить%, например, 100 пикселей, тогда сколько пикселей совпадают или не совпадают (т. Е. 85% или 85 пикселей одинаковы), это то, что я хочу, пожалуйста, помогите

Ответ №3:

Порядок вашего алгоритма равен n ^ 4.

Я думаю, что вы могли бы сократить это до n ^ 3, если вы

  1. перебирайте все возможные цвета.
  2. внутри этого цикла выполните цикл для каждого изображения
  3. найдите вхождения цвета i в каждом изображении
  4. наконец, используйте уравнение для увеличения Counter

Если цвет i встречается x раз в bitmap и y раз в bitmap2 ,

Counter = Counter x*y