簡體   English   中英

如何使用 cv2.imwrite 以 int 16 原始格式保存圖像?

[英]How to saving image by raw with int 16 using the cv2.imwrite?

我在實施 PixelRL 時遇到了問題。 像素RL github 我想使用 int16 ( -32768 ~ 32767 ) 讀取圖像並將其保存為原始數據。 但我找不到如何讓 cv2.imwrite() 支持它。 使用 p = (p[0]*65535+0.5).astype(np.int16) 時,保存 8 位圖像。 有沒有辦法將圖像寫入 int16 和原始數據?

謝謝你。

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)
  

有沒有辦法...?

不。

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

通常,只有 8 位單通道或 3 通道...圖像可以使用此 function 保存,但以下情況除外:

  • 可以保存 16 位無符號 (CV_16U) 圖像...

您可能希望將帶符號的 16 位值轉換為 CV_16U 格式。

或者,您可以考慮編寫 32 位圖像,然后調用后處理程序將它們縮小為您喜歡的 16 位格式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM