Pyplot.imsave() сохраняет изображение правильно, но cv2.imwrite() сохранил то же изображение, что и черный

from scipy.misc import imread
from matplotlib import pyplot

import cv2
from cv2 import cv

from SRM import SRM ## Module for Statistical Regional Segmentation

im = imread("lena.png") 
im2 = cv2.imread("lena.png")
print type(im), type(im2), im.shape, im2.shape 
## Prints <type 'numpy.ndarray'> <type 'numpy.ndarray'> (120, 120, 3) (120, 120, 3)

srm = SRM(im, 256)
segmented = srm.run()

srm2 = SRM(im2, 256)
segmented2 = srm2.run()

pic = segmented/256
pic2 = segmented2/256

pyplot.imshow(pic)
pyplot.imsave("onePic.jpg", pic)

pic = pic.astype('uint8')
cv2.imwrite("onePic2.jpg", pic2)

pyplot.show()

onePic.jpg дает правильное сегментированное изображение, но onePic2.jpg дает полное черное изображение. Преобразование типа данных в uint8 с помощью pic = pic.astype('uint8') не помогло. Я все еще даю черное изображение!

onePic.jpg с помощью pyplot.imsave():

enter image description here

onePic2.jpg с помощью cv2.imwrite():

enter image description here

Пожалуйста, помогите!

Ответ 1

Перед преобразованием pic в uint8 вам нужно умножить его на 255, чтобы получить правильный диапазон.

Ответ 2

Хотя я согласен с @sansuiso, в моем случае я обнаружил возможный крайний случай, когда мои изображения сдвигались либо на один бит вверх по шкале, либо на один бит вниз.

Поскольку мы имеем дело с неподписанными целочисленными значениями, один сдвиг означает возможный недостаточный/переполненный объем, и это может привести к повреждению всего изображения.

Я нашел cv2 convertScaleAbs со значением альфа 255.0, чтобы получить лучшие результаты.

def write_image(path, img):
    # img = img*(2**16-1)
    # img = img.astype(np.uint16)
    # img = img.astype(np.uint8)
    img = cv.convertScaleAbs(img, alpha=(255.0))
    cv.imwrite(path, img)

Этот ответ более подробно.