Home > Blockchain >  How to saving image by raw with int 16 using the cv2.imwrite?
How to saving image by raw with int 16 using the cv2.imwrite?

Time:05-10

I've an issues to implement PixelRL. PixelRL github. I'd like to reading and saving an image to raw data with int16 ( -32768 ~ 32767 ). But I don't find how to make cv2.imwrite() support it. When using p = (p[0]*65535 0.5).astype(np.int16), saving 8bit images. Is there a way to write the image to int16 and raw data?

Thank you.

class MiniBatchLoader(object):

def __init__(self, train_path, test_path, image_dir_path, crop_size):

    # load data paths
    self.training_path_infos = self.read_paths(train_path, image_dir_path)
    self.testing_path_infos = self.read_paths(test_path, image_dir_path)

    self.crop_size = crop_size

# test ok
@staticmethod
def path_label_generator(txt_path, src_path):
    for line in open(txt_path):
        line = line.strip()
        src_full_path = os.path.join(src_path, line)
        if os.path.isfile(src_full_path):
            yield src_full_path

# test ok
@staticmethod
def count_paths(path):
    c = 0
    for _ in open(path):
        c  = 1
    return c

# test ok
@staticmethod
def read_paths(txt_path, src_path):
    cs = []
    for pair in MiniBatchLoader.path_label_generator(txt_path, src_path):
        cs.append(pair)
    return cs

def load_training_data(self, indices):
    return self.load_data(self.training_path_infos, indices, augment=True)

def load_testing_data(self, indices):
    return self.load_data(self.testing_path_infos, indices)

# test ok
def load_data(self, path_infos, indices, augment=False):
    mini_batch_size = len(indices)
    in_channels = 1

    if augment:
        xs = np.zeros((mini_batch_size, in_channels, self.crop_size, self.crop_size)).astype(np.float32)
        
        for i, index in enumerate(indices):
            path = path_infos[index]
            
            img = cv2.imread(path,0)
            if img is None:
                raise RuntimeError("invalid image: {i}".format(i=path))
            h, w = img.shape

            if np.random.rand() > 0.5:
                img = np.fliplr(img)

            if np.random.rand() > 0.5:
                angle = 10*np.random.rand()
                if np.random.rand() > 0.5:
                    angle *= -1
                M = cv2.getRotationMatrix2D((w/2,h/2),angle,1)
                img = cv2.warpAffine(img,M,(w,h))

            rand_range_h = h-self.crop_size
            rand_range_w = w-self.crop_size
            x_offset = np.random.randint(rand_range_w)
            y_offset = np.random.randint(rand_range_h)
            img = img[y_offset:y_offset self.crop_size, x_offset:x_offset self.crop_size]
            xs[i, 0, :, :] = (img/255).astype(np.float32)

    elif mini_batch_size == 0:
        for i, index in enumerate(indices):
            path = path_infos[index]
            
            img = cv2.imread(path,0)
            if img is None:
                raise RuntimeError("invalid image: {i}".format(i=path))

        h, w = img.shape
        xs = np.zeros((mini_batch_size, in_channels, h, w)).astype(np.float16)
        xs[0, 0, :, :] = (img/255).astype(np.float16)

    else:
        raise RuntimeError("mini batch size must be 1 when testing")

    return xs


def test(loader, agent, fout):
sum_psnr = 0
sum_reward = 0
test_data_size = MiniBatchLoader.count_paths(TESTING_DATA_PATH)
current_state = State.State((TEST_BATCH_SIZE,1,CROP_SIZE,CROP_SIZE), MOVE_RANGE)
for i in range(0, test_data_size, TEST_BATCH_SIZE):
    raw_x = loader.load_testing_data(np.array(range(i, i TEST_BATCH_SIZE)))
    raw_n = np.random.normal(MEAN,SIGMA,raw_x.shape).astype(raw_x.dtype)/255
    current_state.reset(raw_x,raw_n)
    reward = cp.zeros(raw_x.shape, raw_x.dtype)*255

    for t in range(0, EPISODE_LEN):
        previous_image = current_state.image.copy()
        action, inner_state = agent.act(current_state.tensor)
        current_state.step(action, inner_state)
        reward = np.square(raw_x - previous_image)*255 - np.square(raw_x - current_state.image)*255
        sum_reward  = cp.mean(reward)*cp.power(GAMMA,t)

    agent.stop_episode()

   
    p = np.maximum(0,current_state.image)
    p = np.minimum(1,p)
    p = (p[0]*65535 0.5).astype(np.int16)
    p = cp.transpose(p,(1,2,0))
 
    cv2.imwrite(output_save_path '/' str(i) '.tiff',p)
  

CodePudding user response:

is there a way ... ?

No.

https://docs.opencv.org/3.4/d4/da8/group__imgcodecs.html#gabbc7ef1aa2edfaa87772f1202d67e0ce

In general, only 8-bit single-channel or 3-channel ... images can be saved using this function, with these exceptions:

  • 16-bit unsigned (CV_16U) images can be saved ...

You might want to munge your signed 16-bit values into CV_16U format.

Alternatively, you might consider writing 32-bit images, and then invoking a post-processing program to shrink them to your favorite 16-bit format.

  • Related