cv2.imwrite changes color when saving from np.array to JPG

7.3k Views Asked by At

I am currently working on an edge detection program for a class (concretely I am detecting street lines).

I read in an image and detect some edges (via hough). The detected edges are then laid onto the original image. In the process, image data is stored as numpy.ndarry. At the very end, i want to save the image to disc (as jpg).

If I write the images to disc via scipy.misc.imsave, everything works fine. If I do it via cv2.imwrite, the colors get distorted into a sort of thermal picture.

I have read several topics on different color channels and necessary scaling / conversion, but I cannot find a solution from numpy.ndarray to .jpg. I know that .jpg may only have 8bit or 16bit color channels, but don't know where to go from there. In any case i have blindly tried to divide by 255 (--> image almost black) and multiply by 255 (--> whitish thermal picture :-) ).

Any ideas? These are the relevant sections of code:

Reading the image (function is later called in a loop):

def read(img):
    image = mpimg.imread(img)
    return image

Draw function to be called in a loop to draw all lines defined in an array:

def draw_lines(img, line_coordinates, color=[255, 0, 0], thickness=4):
    for line in line_coordinates:
        for x1, y1, x2, y2 in line:
            cv2.line(img, (x1, y1), (x2, y2), color, thickness)

This function calls the draw function and returns an image with all lines drawn

def depict_lines(img, array_of_coordinates): 
    line_img = np.zeros((img.shape[0], img.shape[1], 3), dtype=np.uint8)
    draw_lines(line_img, array_of_coordinates)
    return line_img

Next, I combine the original image and the one containing the edges:

def weighted_img(line_img, initial_img, α=0.95, β=1., λ=0.):
    return cv2.addWeighted(initial_img, α, line_img, β, λ)

combined_images = weighted_img(depicted_lines, original_image)

Finally, I save the image to disc. This call produces weird colors:

cv2.imwrite(new_file_name, combined_images)

whereas this one works fine:

scipy.misc.imsave('outfile.jpg', combined_images)

This is an unprocessed image: natural colors

And a processed one: distorted colors

Your help would be appreciated!

1

There are 1 best solutions below

2
On BEST ANSWER

@ZdaR you were right, cv2.imwrite needs BGR. I just included the following line:

image_to_write = cv2.cvtColor(combined_images, cv2.COLOR_RGB2BGR)

And now this outputs images just fine:

cv2.imwrite(new_file_name, image_to_write)

Thanks! For now, I will not accept my own answer as a solution; maybe someone has a more comprehensive one she or he would like to post.