Author Topic: Seek Compact Pro python script?  (Read 8715 times)

0 Members and 1 Guest are viewing this topic.

Offline pauleddTopic starter

  • Regular Contributor
  • *
  • Posts: 77
  • Country: de
  • Riesige Gepanzerte Luftschiffe
Re: Seek Compact Pro python script?
« Reply #25 on: June 27, 2018, 06:58:43 am »
But your camera is a non-fast frame unit, correct?  OR does the Seek app identify it as Seek Compact PRO FF (like it does with my camera)?
Yes, its the normal CompactPro (ID 289d:0011)

I currently trying to figure out whether my frames are valid ones or whether where to look for the actual image in it. I only concentrate on the nomal frames with id=3.

I got a function from stackoverflow that converts all pairs of uint8 values to into a single uint16 value (I guess this is what happens in the correct_endianness function in the libseek-thermal lib). Of cause the size off the array is then half 177840 = 88920...

Code: [Select]
while (status != 3):
frame = []
send_msg(0x41, 0x53, 0, 0,'\x58\x5B\x01\x00')
frame = dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
status = frame[4]
if (status == 3):
frame16 = array.array('H', ((j << 8 ) | i
  for (i,j)
  in zip(frame[::2], frame[1::2])))
print "frame_uint8=", frame[:32]
print "frame_uint16=", frame16[:32]
Here I've printed two lines with 32 positions for the same id=3 frame, the first is the unprocessed uint8 frame, the second is the uint16 array with the data from the uint8 array. Now in the uint16 data I can see that the frame_count byte is at index frame16[1]=33, and the frame_id byte is at frame16[2] = 3, as expected... the index for those two changed to the half number (the frame_id in the uint16 was at frame[4]):
Code: [Select]
frame_uint8= array('B', [121, 5, 33, 0, 3, 0, 0, 0, 33, 0, 31, 25, 152, 58, 0, 0, 0, 0, 0, 0, 48, 0, 37, 55, 0, 0, 0, 0, 0, 0, 0, 0])
frame_uint16= array('H', [1401, 33, 3, 0, 33, 6431, 15000, 0, 0, 0, 48, 14117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

I am not shure if I can simply throw the frame16 data into an cv2::Mat/PIL::whatever to display the image or whether I need to crop the raw dimensions to the 320x240, and if so, I am not sure how to do it. The writer of this python code just put the array into "calimg = Image.fromstring("I", (208,156), ret9, "raw", "I;16")" without cropping it to 207x154 for the "Compact"...

I know the C++ code in the libseek-thermal lib contains all the steps but I am quite awkward in understanding it  :o . Thats why I take it to pieces here in python ;D
« Last Edit: June 27, 2018, 07:03:20 am by pauledd »
human being - without Windows® - excuse my bad english
 

Offline IwuzBornanerd

  • Frequent Contributor
  • **
  • Posts: 318
  • Country: us
Re: Seek Compact Pro python script?
« Reply #26 on: June 27, 2018, 07:39:21 am »
Once you have converted to 16 bit numbers you then need to subtract the values in the shutter frame (ID=1) from the frame 3 values.  This gets you values that correspond to the difference in temperature between the shutter & the scene.  The values can be both negative & positive.  That is the first level of correction.  You then need to apply gain correction factors to each pixel.  You can use the values in the frame with ID=4 by dividing each number by the average of all values and using the results as percentage multipliers for each pixel in the frame 3 minus frame 1 set of values.  OR you can make your own correction factors (which are better) by capturing a frame 3 with the camera warmed up & pointed at a uniform ambient temperature surface, subtracting the preceding frame 1 from that and dividing each value by the average.   I think I have that right without reviewing my code.  You will have to figure out a good way to deal with the +/- values & assigning colors or gray shades.  Adding a simple offset is one way.  Figuring temperature is another complexity...

Is that clear as mud?  ;) 
I am not opposed to exercise, unless it is an exercise in futility.
 

Offline pauleddTopic starter

  • Regular Contributor
  • *
  • Posts: 77
  • Country: de
  • Riesige Gepanzerte Luftschiffe
Re: Seek Compact Pro python script?
« Reply #27 on: June 28, 2018, 06:47:48 am »
*to the note, just in case I cant remember again later...

I am currently still totally stuck at raw conversion  :clap:
I went some steps backward and simply outputted the raw frames in binary format like that:

Code: [Select]
while status != 3:
frame = np.uint16()
send_msg(0x41, 0x53, 0, 0,'\x58\x5B\x01\x00')
frame = dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
status = frame[4]
print status

thefile = open("frames/frame_id_"+str(status)+".raw", 'w')
thefile.write(struct.pack('177840B', *frame))

I now have:
Code: [Select]
frame_id_14.raw
frame_id_1.raw
frame_id_3.raw
frame_id_4.raw
frame_id_5.raw
frame_id_6.raw
frame_id_7.raw
frame_id_8.raw
frame_id_9.raw

I then used imagemagik to convert them:

Code: [Select]
for i in $(ls frames/);do convert -depth 16 -endian lsb -size 342x260 gray:$i -auto-level $i.png;done
conversion failed for id: 4,8,9,14 "convert: no images defined"

for the rest I got these images:
id1

id3

id5

id6

id7


In id3 I can see the faint thermal object my cam is pionting at... I get closer  :)


Just another sidenote:
ALL the camera initialisation steps from:
Code: [Select]
# SET_OPERATION_MODE = 60; 0x41=send,0x3C=60
send_msg(0x41, 0x3C, 0, 0, '\x00\x00')
...
down to:
Code: [Select]
...
# GET_FIRMWARE_INFO = 78 = 0x4E
ret7 = receive_msg(0xC1, 0x4E, 0, 0, 64)
can be deleted. I found out after accidental delete that the cam starts image transfer with just this commands:
Code: [Select]
#SET_IMAGE_PROCESSING_MODE = 62 = 0x3E
send_msg(0x41, 0x3E, 0, 0,'\x08\x00')

# SET_OPERATION_MODE = 60 = 0x3C
send_msg(0x41, 0x3C, 0, 0,'\x01\x00')
after that you can start the bulk transfer... This seems to work at least for my CompactPro device...

I now continue to fiddle with that  :palm: array stuff that my script outputs raw png's...
« Last Edit: June 28, 2018, 06:49:37 am by pauledd »
human being - without Windows® - excuse my bad english
 
The following users thanked this post: DaneLaw

Offline IwuzBornanerd

  • Frequent Contributor
  • **
  • Posts: 318
  • Country: us
Re: Seek Compact Pro python script?
« Reply #28 on: June 28, 2018, 08:34:09 am »
I also found that much of the setup stuff can be eliminated, but I can't verify if it is the same stuff you deleted.  I suppose most of it is "defaults"
I am not opposed to exercise, unless it is an exercise in futility.
 

Offline pauleddTopic starter

  • Regular Contributor
  • *
  • Posts: 77
  • Country: de
  • Riesige Gepanzerte Luftschiffe
Re: Seek Compact Pro python script?
« Reply #29 on: June 28, 2018, 05:05:02 pm »
I made a good step foreward :). After hours fiddling with lists/numpy-arrays/opencv/endianness  :rant:
I managed to get Images from opencv. The problem was simple... I simply did not realize that the data in my lists/numpy-arrays was 1d... for displaying/manipulating images in numpy arrays with opencv I needed the data to be 2d. So one simple numpy function called reshape did the job.
And I found a simpler way to convert the raw frame from uint8 LSB to uint16 MSB:

Code: [Select]
...
frame = dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
frame += dev.read(0x81, 0x3570, tout)
...
npframe = np.asarray(frame, dtype='<B')
npframe.dtype = np.uint16
img = npframe.reshape(260,342)
cv2.normalize(img,img, 0,65535,cv2.NORM_MINMAX)
cv2.namedWindow("image", cv2.WINDOW_NORMAL)
cv2.resizeWindow('image', 600,600)
cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Now I can define an ROI and cut out the actual image from the raw frame and start all the post processing stuff that I want. One thing I found interesting was that the actual image has dimensions wider than those from the
specs  ??? I just googled for 324x254 and found that others here had already discovered that. So
for the CompactPro I get 4-top, 18-right and2-bottom lines that are outside of the image.
human being - without Windows® - excuse my bad english
 

Offline pauleddTopic starter

  • Regular Contributor
  • *
  • Posts: 77
  • Country: de
  • Riesige Gepanzerte Luftschiffe
Re: Seek Compact Pro python script?
« Reply #30 on: July 05, 2018, 04:39:51 pm »
I just wonder where this "patent pixels" are in my id3 image above? Are that the total black pixels that cover 2 pixels each? Would be strange if that would be dead pixels, but I would expect the patent to be in a pattern well ordered over the whole image as I saw from the other users here  :o
human being - without Windows® - excuse my bad english
 

Offline IwuzBornanerd

  • Frequent Contributor
  • **
  • Posts: 318
  • Country: us
Re: Seek Compact Pro python script?
« Reply #31 on: July 05, 2018, 07:06:11 pm »
My Pro does not have "patent pixels"; at least not a noticeable number of regular (or even irregular) zero pixels.
I am not opposed to exercise, unless it is an exercise in futility.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf