I am trying to use the cv2 LUT to do a image transfer in Python. The LUT needs to be has same number of channels as the image. But I can't solve one error:
image1Transfered = cv2.LUT(image1, lut) cv2.error: /build/buildd/opencv-2.3.1/modules/core/src/convert.cpp:1037: error: (-215) (lutcn == cn || lutcn == 1) && lut.total() == 256 && lut.isContinuous() && (src.depth() == CV_8U || src.depth() == CV_8S) in function LUT
Here is the python code, I believe I can split the image to multiple single channels and apply the LUT respectively. But this is waste of resource.
#!/usr/bin/python
import sys
import cv2
import numpy as np
image1 = cv2.imread("../pic1.jpg", 1)
# apply look up table
lut = np.arange(255, -1, -1, dtype = image1.dtype )
lut = np.column_stack((lut, lut, lut))
image1Converted = cv2.LUT(image1, lut) # <-- this is where it fails
Thank you for your time.
You are using np.column_stack()
to create a 3-channel image, but that is not the right function. You have to use either np.dstack()
or cv2.merge()
. Then it works fine.
eg:
In [3]: x
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
In [5]: np.column_stack((x,x,x))
array([[0, 1, 2, 0, 1, 2, 0, 1, 2],
[3, 4, 5, 3, 4, 5, 3, 4, 5],
[6, 7, 8, 6, 7, 8, 6, 7, 8]])
In [6]: np.dstack((x,x,x))
array([[[0, 0, 0],
[1, 1, 1],
[2, 2, 2]],
[[3, 3, 3],
[4, 4, 4],
[5, 5, 5]],
[[6, 6, 6],
[7, 7, 7],
[8, 8, 8]]])
In [11]: cv2.merge((x,x,x))
array([[[0, 0, 0],
[1, 1, 1],
[2, 2, 2]],
[[3, 3, 3],
[4, 4, 4],
[5, 5, 5]],
[[6, 6, 6],
[7, 7, 7],
[8, 8, 8]]], dtype=int32)
Thank you Abid, I like your blog. I am going through you Python CV post one by one. It's a great help on learning Python opencv. You did a very nice work.
Here is what I ended up with:
lut3 = np.column_stack((lut, lut, lut))
lutIdxDot = np.array( [0, 1, 2], dtype=int)
lutIdx0 = np.zeros( image1.shape[0] * image1.shape[1], dtype=int)
lutIdx1 = np.ones( image1.shape[0] * image1.shape[1], dtype=int)
lutIdx2 = lutIdx1 * 2
lutIdx = np.column_stack((lutIdx0, lutIdx1, lutIdx2))
lutIdx.shape = image1.shape
image1Rev = lut3[image1, lutIdx] # numpy indexing will generate the expected LUT result.
I used the numpy indexing to get the result. I didn't use the cv LUT function. The performance is unknown to me.
The last line of code was strange to me at first. The indexing is a very interesting feature of numpy. When the code run to the last line, the lut3 is:
ipdb> p lut3
array([[255, 255, 255],
[254, 254, 254],
[253, 253, 253],
[252, 252, 252],
...
[ 2, 2, 2],
[ 1, 1, 1],
[ 0, 0, 0]], dtype=uint8)
ipdb> p lutIdx
array([[[0, 1, 2],
[0, 1, 2],
[0, 1, 2],
...,
...,
[0, 1, 2],
[0, 1, 2],
[0, 1, 2]]])
lutIdx has the same shape of the image1. The lut3[image1, lutIdx] is asking for an array as the result that its shape is same with image1, and lutIdx. Its values are from lut3. For each item of image1, use lut[image1's Value of that spot, lutIdx's Value of that spot] to find that output value. (I wish I can draw a diagram.)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.