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:

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
delrocco
  • 495
  • 1
  • 4
  • 23

2 Answers2

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
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • 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 Jan 24 '18 at 23:56
  • @delrocco Then copy it to another image, I will update my answer. :D – eyllanesc Jan 24 '18 at 23:57
  • 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 Jan 25 '18 at 00:00
  • @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. – eyllanesc Jan 25 '18 at 00:04
  • 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 :/ – delrocco Jan 25 '18 at 00:19
  • @delrocco Exactly, if you want to handle speed, the most common thing that libraries do is not exchange values, but memory positions, it is less expensive to move a variable than hundreds or thousands of them. – eyllanesc Jan 25 '18 at 00:22
  • yes of course. just misunderstanding on my part of numpy array since I am new to it. but thank you for both solutions. I just duplicated the numpy array instead of the QImage, which turned out to be much faster, then did the list slicing. – delrocco Jan 25 '18 at 00:30
  • @delrocco Many times you will have to decide: memory consumption or speed, so for the following questions say clearly what you want. – eyllanesc Jan 25 '18 at 00:31
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)
Tyler Cowan
  • 820
  • 4
  • 13
  • 35
  • I started doing this, but figured it was a "naive" solution. Would a lambda be better/faster? Or would this work just as fast? – delrocco Jan 24 '18 at 23:54
  • 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. – Tyler Cowan Jan 24 '18 at 23:55
  • 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. – delrocco Jan 24 '18 at 23:59
  • 1
    This might help you figure out performance http://www.benjaminmgross.com/matching-performance-using-python-listss-ndarrays-and-pandas/ – Tyler Cowan Jan 25 '18 at 00:04
  • 1
    define `order` before the loop, you are creating that variable without need in each iteration. – eyllanesc Jan 25 '18 at 00:20