0

I'm still new to numpy and having trouble writing a lambda to do what I want in this case. It could be that the lambda is not working because of the data in the array?

I've got some pixel values from a QImage in Qt5 using PyQT in Python:

ptr = self.myPhoto.bits()
ptr.setsize(self.myPhoto.byteCount())
pixels = np.asarray(ptr).reshape(self.myPhoto.height(), self.myPhoto.width(), 4)

The pixel data looks like this [[[B G R A]]]:

[[[  100   0   2 255]
  [  100   0   2 255]
  [  100   1   1 255]
  ..., 
  [  2   3   0 255]
  [  1   2   0 255]
  [  1   2   0 255]]]

I want it to look like this [[[R G B A]]]:

[[[  2   0 100 255]
  [  2   0 100 255]
  [  1   1 100 255]
  ..., 
  [  0   3   2 255]
  [  0   2   1 255]
  [  0   2   1 255]]]

EDIT: removed commas from array

Also, is it possible to do this right from reshape call instead of using a lambda post process?

These questions are interesting, but I'm still having trouble glueing them together to get what I want:

2 Answers 2

2
  • PyQt:

One possible solution is to use rgbSwapped(), this method converts RGB to BGR:

self.myPhoto = self.myPhoto.rgbSwapped()
ptr = self.myPhoto.bits()
ptr.setsize(self.myPhoto.byteCount())
pixels = np.asarray(ptr).reshape(self.myPhoto.height(), self.myPhoto.width(), 4)
  • Using Numpy:

using slicing

ptr = self.myPhoto.bits()
ptr.setsize(self.myPhoto.byteCount())
pixels = np.asarray(ptr).reshape(self.myPhoto.height(), self.myPhoto.width(), 4)

r = np.copy(pixels[:,:,0])
pixels[:, :, 0] = pixels[:,:,2]
pixels[:, :, 2] = r
Sign up to request clarification or add additional context in comments.

8 Comments

Re: PyQT - This effectively gives me what I want, but I have to duplicate the object right? Because I can't lose my original RGB image.
@delrocco Then copy it to another image, I will update my answer. :D
lol no I understand that. I mean that is the weakness of that solution is that I have to duplicate the memory for it. That's all I meant. But I am looking at your new solution.
@delrocco No, in my initial solution the memory was not duplicated since it replaced the previous memory space. On the other hand I understood you with your initial comment that you did not want to lose the initial image.
Your second solution opened my eyes to something else! I thought numpy was making a copy of the pixels from the pointer to the QImage bits. But when I manipulate that pixels numpy array, it directly affects my original QImage. So... I am going to have to duplicate the memory anyway because I need both sets :/
|
1

How about this solution? you can use tolist() before sending it through this

order = [1,0,2,3]
test = [[[100,0,2,255],
  [100,0,2,255],
  [100,1,1,255]]]

print(test)

for i in range(0,len(test)):
    for j in range(0,len(test[i])):
        temp = test[i][j]
        temp = [temp[k] for k in order]
        test[i][j] = temp

print(test)

5 Comments

I started doing this, but figured it was a "naive" solution. Would a lambda be better/faster? Or would this work just as fast?
I believe a lambda is faster but unless your processing large arrays in the millions I wouldnt imagine so slow you cant use it. I would try it and see if your happy with the speed and then figure out the lambda later. By faster I think were talking milliseconds I am sure someone who is willing to test will chime in.
Ok, I'll fall back on this. I am working with 4368x2912 HDR images, and the user can flip through them as fast as a mouse wheel, so I'd like it as fast as possible. But I will try it.
This might help you figure out performance benjaminmgross.com/…
define order before the loop, you are creating that variable without need in each iteration.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.