Я использую сжатие lz77 для изображений. Но если я вставлю изображение RGB, результат будет неправильным, может ли кто-нибудь из вас мне помочь?

когда я вставляю изображение в градациях серого, алгоритм работает, если я вставляю изображение в формате RGB, вывод будет неправильным. правильно ли я работаю с изображением rgb? Я не понимаю, почему мне могут помочь?

используемая библиотека

from PIL import Image

импортировать numpy как np из cv2 import cv2

 def lz77Compress (image,sw,lab):
    img = cv2.imread(image)
    print("Initial size", img)
    flat = np.array(img).flatten()
    #cv2.imshow("input", img)
    row = img.shape[0]
    col = img.shape[1]
    tot = row * col
    slidingWindows = sw
    lookAhead = lab 

массив кортежей и символов

encodedTuple = np.array([]) 
encodedChar = np.array([])

указатель в буфере поиска

sbPointer = 0
while sbSize + sbPointer < tot :
    max_match = 0
    max_match_go_back = 0        
    selChar = sbPointer + sbSize

пустая последовательность

   seqY = np.array([])
    for i in range(sbPointer,sbPointer + sbSize):
        if(flat[i] == encodeCharacters):
            seqY = np.append(seqY,i)

проверьте, есть ли совпадение в lookAheadBuffer

 if(seqY.size == 0 ):
        encodedTuple = np.append(encodedTuple,(0,0))
        encodedChar = np.append (encodedChar,encodeCharacters)
    else:

        for j in seqY:
        #lunghezza della corrispodenza
            matchLenght= 0
            returnBack = selChar -i
            it = 0 
            while selChar + it < tot :
                if flat[it + j] == flat[selChar + it]:
                    matchLenght +=1
                    it +=1
              # se non trova corrispondenze
                else: 
                    break
            if matchLenght>max_match:
               max_match = matchLenght
               returnBack = max_match_go_back

сохранить соответствие и кортеж в массиве

encodedTuple = np.append(encodedTuple,(max_match_go_back,max_match))
encodedChar = np.append(encodedChar,flat[selChar + max_match - 1])
        
       sbPointer+= 1 +max_match

** сохранение encodedTuple, encodedChar, файла compresses.txt и размера распаковки **

print("Prova", encodedTuple, encodedChar)
print("ArrayBin",encodedTuple.tolist(), encodedChar.tolist())
np.save("encodedTuple", encodedTuple) 
np.save("encodedChar", encodedChar)
a = encodedTuple.tolist()
b = encodedChar.tolist()
c= (a,b)
print("File compresso in : Copressed.txt")
output = open("Compressed.txt","w+")
output.write(str(c))
imgSize = open('imgSize.txt', "w")
imgSize.write(str(row) + '\n')  # write row dimension
imgSize.write(str(col) + '\n')  # write col dimension
cv2.waitKey(0)
cv2.destroyAllWindows()

**Главный **

path = "./im3.jpg"

lz77Compress (путь, 500,500)


person giangri_93    schedule 02.04.2021    source источник
comment
Изображение RGB имеет 3 канала (в большинстве случаев). Попробуйте добавить ch = img.shape[2] после col = img.shape[1] и tot = row * col * ch. Или лучше: tot = img.size. Если проблема не в этом, отправьте образец кода, который воспроизводит проблему - код, который кто-то может скопировать, вставить и выполнить.   -  person Rotem    schedule 03.04.2021
comment
Я добавил ch, но теперь у меня есть эта проблема: Файл c: /Users/anton/Desktop/Progetto/test.py, строка 17, в ‹module› lz77Compress (путь, 500,500) Файл c: \ Users \ anton \ Desktop \ Progetto \ image.py, строка 35, в lz77Compress encodeCharacters = flat [selChar] IndexError: индекс 206 выходит за границы оси 0 с размером 206   -  person giangri_93    schedule 03.04.2021
comment
В случае, если вы решите опубликовать код, который я действительно могу выполнить, дайте мне знать.   -  person Rotem    schedule 03.04.2021
comment
@Rotem в комментарии я не могу разместить код, потому что он длинный, я даю вам свою ссылку github github.com/Anto-9393/project-multimedia-lz77. Спасибо за вашу помощь   -  person giangri_93    schedule 03.04.2021


Ответы (1)


В большинстве случаев изображение RGB имеет 3 цветовых канала, а серое изображение - 1 цветовой канал.

  • Предположим, что img - это массив NumPy, представляющий серое изображение:
    img.shape будет (rows, cols), а img.size будет _5 _ * _ 6_.
  • Предположим, что img - это массив NumPy, представляющий изображение RGB (или BGR):
    img.shape будет (rows, cols, ch), а img.size будет _11 _ * _ 12 _ * _ 13_.
    В случае RGB ch = 3.

Я загрузил ваш код с github.
Я видел, что вы уже исправили код для поддержки изображений RGB.

Я не могу воспроизвести ошибку в строке 35 файла image.py
Вы ее исправили?

Проблемы, которые я смог найти:

  • Вы не закрываете файлы:
    Закройте файлы в конце lz77Compress:

     # We must close the files.
     output.close()
     imgSize.close()
    

Вам лучше также закрыть imsize после прочтения row, col, ch в lz77Decompressor.

  • При использовании cv2.imshow("output", decodeArray) вам нужно, чтобы тип decodeArray был uint8.
    Вы можете использовать следующий код для отображения вывода:

     cv2.imshow("output", decodeArray.astype(np.uint8)) # Show as uint8
    

Если вы хотите поддерживать и серый, и RGB, вы можете проверить, len(img.shape) это 2 или 3, и добавить логику в декомпрессор.

Примечание.
Я не просматривал весь код, поэтому могут быть проблемы, которые я пропустил.

person Rotem    schedule 03.04.2021
comment
Прежде всего хочу поблагодарить вас за ваши предложения. Я решил, но теперь у меня проблема со скоростью сжатия. С маленькими изображениями (205 204) алгоритм занимает 1 минуту, а с большими изображениями время значительно увеличивается. Как я мог оптимизировать код? p.s только начинают работать с python. - person giangri_93; 05.04.2021
comment
Когда мне нужно что-то для быстрой работы, я использую C, а не Python. Циклы в Python очень медленные, поэтому по возможности старайтесь избегать длинных циклов. Проверьте свою реализацию, чтобы увидеть, есть ли петли, которых можно избежать. Я не знаю, актуально ли это, но попробуйте использовать векторизованные операции (используя NumPy), когда это необходимо. Если вы не можете избежать использования циклов, вы можете попробовать Cython и / или Numba. Обратите внимание, что мой опыт работы с Python ограничен. - person Rotem; 05.04.2021
comment
github.com/Anto-9393/project-multimedia-lz77 Я сделал несколько изменений, алгоритм ускорился, но теперь финальное изображение видно только наполовину. Какие-либо предложения? - person giangri_93; 06.04.2021
comment
Что ж ... Я знаю, что это сложно, но вам придется отлаживать свой код. - person Rotem; 06.04.2021
comment
@ Rotem: не могли бы вы сказать мне, почему у меня эта проблема в этом алгоритме? : stackoverflow.com/questions/67043929/ - person giangri_93; 11.04.2021