opencv 处理图像后RGB消失

zkure5ic  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(220)

我正在处理一个图像(2192 x 2921 x 3),将等于0的像素值替换为它以前的非零值。
代码完成时没有出现错误,但输出图像不再是RGB。
我的代码中有什么错误导致了这个吗?
函数“fill_zeros_with_last“来自StackOverflow
代码如下:

import numpy as np
import cv2
from PIL import Image

def fill_zeros_with_last(arr):
    prev = np.arange(len(arr))
    prev[arr == 0] = 0
    prev = np.maximum.accumulate(prev)
    return arr[prev]

image = cv2.imread('path\to\image')
image_modified = [] # to store the processed image
for k in range(3):
    for j in range(2921):
        image1 = fill_zeros_with_last(image[:, j, k]) # replaces 0s with the previous nonzero value.
        image_modified.append(image1)

image_modified = np.reshape(image_modified, ((2192, 2921, 3))) # to reshape the image
image_modified = image_modified.astype('uint8') # convert to uint8
img1 = Image.fromarray(image_modified, 'RGB') # convert to RGB
img1.save('image_modified.png') # save image

下面是一个输入图像示例:

示例输出:

8ulbf1ek

8ulbf1ek1#

看起来您对存储OpenCV图像的NumPy数组的数据排序感到困惑。
OpenCV中图像的自然排序(在内存中)是“原始主要”,即bgrbgr ......数据排序:

Row 0: BGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGR
Row 1: BGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGR
Row 3: BGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGRBGR

image数组的索引为:image[r, c, ch](行、列、颜色通道):
image_modified是已修改的列表,列表中的每个元素应用一个颜色通道:

[                            
  All columns of blue channel of column  
  Applies image column 0: BBBBBBBBBBBBBBBBBBBBBBBBBBB,
  Applies image column 1: BBBBBBBBBBBBBBBBBBBBBBBBBBB,
  Applies image column 2: BBBBBBBBBBBBBBBBBBBBBBBBBBB,
  All columns of green channel of column  
  Applies image column 0: GGGGGGGGGGGGGGGGGGGGGGGGGGG,
  Applies image column 1: GGGGGGGGGGGGGGGGGGGGGGGGGGG,
  Applies image column 2: GGGGGGGGGGGGGGGGGGGGGGGGGGG,
  All columns of red channel of column
  Applies image column 0: RRRRRRRRRRRRRRRRRRRRRRRRRRR,
  Applies image column 1: RRRRRRRRRRRRRRRRRRRRRRRRRRR,
  Applies image column 2: RRRRRRRRRRRRRRRRRRRRRRRRRRR,
  ...
]

为了固定顺序,我们可以应用np.reshape,然后应用np.transpose

  • 按行按元素将形状调整为3列< cols >< rows >:
image_modified = np.reshape(image_modified, ((3, cols, rows)))
  • 通过cols3转置(置换)到rows
image_modified = np.transpose(image_modified, (2, 1, 0))

代码示例:

import numpy as np
import cv2

def fill_zeros_with_last(arr):
    prev = np.arange(len(arr))
    prev[arr == 0] = 0
    prev = np.maximum.accumulate(prev)
    return arr[prev]

image = cv2.imread('test_image.jpg')
rows, cols = image.shape[0], image.shape[1]  # Get height and width of image

image_modified = [] # to store the processed image

for k in range(3):
    for j in range(cols):
        image1 = fill_zeros_with_last(image[:, j, k]) # replaces 0s with the previous nonzero value.
        image_modified.append(image1)

image_modified = np.reshape(image_modified, ((3, cols, rows))) # to reshape the image
image_modified = np.transpose(image_modified, (2, 1, 0))  # Fix the data ordering to match OpenCV convention

cv2.imwrite('image_modified.png', image_modified)  # Use cv2.imwrite instead of using PIL because the color ordering is different.

我们可以使用NumPy数组来存储image_modified,而不是使用列表,而不是打乱顺序:

import numpy as np
import cv2

def fill_zeros_with_last(arr):
    prev = np.arange(len(arr))
    prev[arr == 0] = 0
    prev = np.maximum.accumulate(prev)
    return arr[prev]

image = cv2.imread('test_image.jpg')

rows, cols = image.shape[0], image.shape[1]  # Get height and width of image

#image_modified = [] # to store the processed image
image_modified = np.zeros_like(image)  # Initialize image_modified to array of zeros with same size and type of image

for k in range(3):
    for j in range(cols):
        image1 = fill_zeros_with_last(image[:, j, k]) # replaces 0s with the previous nonzero value.
        image_modified[:, j, k] = image1  # Update the column
        #image_modified.append(image1)

cv2.imwrite('image_modified.png', image_modified)  # Use cv2.imwrite instead of using PIL because the color ordering is different.

输出量:

相关问题