supplierdeeply

Face Detect Trigger?

  • 20 Replies
  • 2289 Views
*

Offline reyalp

  • ******
  • 10069
Re: Face Detect Trigger?
« Reply #10 on: 24 / June / 2012, 16:16:39 »
Advertisements
So is there a chance it could get re-merged? or are we losing this function forever :( ?
There is a chance, but using the screen re-draw seems pretty hokey to me. If you tell me which camera and firmware version you have, I'll try to make you a test build with this feature in it.

I did some digging in the Canon face code yesterday and it seems like there should be a better way. If that turns out to be a dead end, then I'll consider re-adding this.

Don't forget what the H stands for.

*

Offline Naito

  • *
  • 19
Re: Face Detect Trigger?
« Reply #11 on: 24 / June / 2012, 23:06:15 »
So is there a chance it could get re-merged? or are we losing this function forever :( ?
There is a chance, but using the screen re-draw seems pretty hokey to me. If you tell me which camera and firmware version you have, I'll try to make you a test build with this feature in it.

I did some digging in the Canon face code yesterday and it seems like there should be a better way. If that turns out to be a dead end, then I'll consider re-adding this.

I agree, it does seem hokey to do it that way.  I'm trying to put it on a SX110 and an SD1000 camera, is there anything I can do to help?  I'm not much help with C coding, but I can write scripts well.

*

Offline reyalp

  • ******
  • 10069
Re: Face Detect Trigger?
« Reply #12 on: 25 / June / 2012, 00:59:03 »
I've adapted the old chdkde code attached a trunk build for sx110 (100b, the only known firmware). If you let me know which version of the sd1000 you have, I can do one for that.

It looks like this code will still run regular motion detection on the Y values, so you'll want to set the threshold high.

The example script in http://trac.assembla.com/chdkde/browser/trunk/CHDK/SCRIPTS/MD?rev=99 seemed to work for me in a very brief test.

This is a trunk build, so you need the modules from the zip, as well as the diskboot.bin / ps.fi2
I agree, it does seem hokey to do it that way.  I'm trying to put it on a SX110 and an SD1000 camera, is there anything I can do to help?  I'm not much help with C coding, but I can write scripts well.
My first idea, which hasn't panned out so far was that the information might be in a propcase. You mentioned that you went through them with get_prop_str, but unless you have the correct sizes, it would be easy to miss something. I thought propcase 9 (for propset 2, length 156 bytes) looked likely, because it is read and set in face detection related tasks. But after playing with it, I didn't see anything that clearly indicated if a face was detected. Also it (like most propcases) only seems to update on halfpress.

There are some other large propcases that might be candidates, 0x70 (length 300 bytes) is also used in these tasks.

I've attached a list of all the propcase numbers and sizes I got from extracting all the propcase related calls I could find from the d10 firmware. This is a propset 2 camera, so should be applicable to your cameras if you want to look more.

The approach I'm looking into now is variables referenced by the face detection tasks. Unfortunately, canon didn't put many log messages in this area, so it's quite difficult to figure out what is going on. I've found at least 3 face detection related tasks:
FaceFrame
DispFace
ChaceFace
Don't forget what the H stands for.

*

Offline reyalp

  • ******
  • 10069
Re: Face Detect Trigger?
« Reply #13 on: 25 / June / 2012, 01:10:49 »
Here's a patch for the current trunk with these changes.
Don't forget what the H stands for.


*

Offline reyalp

  • ******
  • 10069
Re: Face Detect Trigger?
« Reply #14 on: 25 / June / 2012, 02:15:03 »
Good news and bad news.

Good news: I'm pretty sure I've found a variable that stores the number of faces, in a structure shared by DispFace and ChaseFace.  On D10, this structure is at 0x193A4, and the face count is a 16 bit int at offset 0xC. This address is found at the start of ChaseFace.

This seems to run all the time, whether you are in face detect mode or not, and reacts quite quickly. The value updates both in plain live view and half press. It's even updated in MF :o

If you find the equivalent address on your cameras, it should be  trivial to write face detect script with this using peek, e.g:
Code: [Select]
face_count_addr=0x193b0
while peek(face_count_addr,2) < 1 do
sleep(10)
end
shoot()

Bad news: I don't see ChaseFace or DispFace in sx110. However, I do see some apparently face related debug strings that don't exist on d10:
Code: [Select]
ROM:FFDA5E38                 LDR     R6, =0x54D9C
ROM:FFDA5E3C                 ADR     R0, aDetectfaceinfo ; "\r\n  DetectFaceInfo#%u"
ROM:FFDA5E40                 LDRH    R1, [R6]
ROM:FFDA5E44                 BL      nullsub_218
ROM:FFDA5E48                 LDRH    R2, [R6,#4]
ROM:FFDA5E4C                 LDRH    R1, [R6,#2]
ROM:FFDA5E50                 ADR     R0, aHsizeUVsizeU ; "\r\n  Hsize = %u, Vsize = %u"
ROM:FFDA5E54                 BL      nullsub_218
ROM:FFDA5E58                 LDRH    R1, [R6,#6]
ROM:FFDA5E5C                 ADR     R0, aNum_of_resultU ; "\r\n  Num_Of_Result = %u"
ROM:FFDA5E60                 BL      nullsub_218
ROM:FFDA5E64                 LDRH    R1, [R6,#8]
ROM:FFDA5E68                 ADR     R0, aAll_num_of_res ; ", All_Num_Of_Result = %u"
ROM:FFDA5E6C                 BL      nullsub_218
ROM:FFDA5E70                 LDR     R1, [R6,#0xC]
ROM:FFDA5E74                 ADR     R0, aFsetframeinfoD ; "\r\n  fSetFrameInfo = %d"
ROM:FFDA5E78                 BL      nullsub_218
ROM:FFDA5E7C                 LDR     R1, [R6,#0x10]
ROM:FFDA5E80                 ADR     R0, aFexistprimaryf ; ", fExistPrimaryFace = %d"
If you use peek (or the memory browser and misc debug display) to look at the above offset from 0x54D9C, you may find something useful.

sd1000 looks to be different still...
« Last Edit: 25 / June / 2012, 02:17:18 by reyalp »
Don't forget what the H stands for.

*

Offline Naito

  • *
  • 19
Re: Face Detect Trigger?
« Reply #15 on: 25 / June / 2012, 10:26:25 »
Wow that's quick work!
ok, lots to respond to here:

f you let me know which version of the sd1000 you have, I can do one for that.
my SD1000 is the 1.02a
My first idea, which hasn't panned out so far was that the information might be in a propcase. You mentioned that you went through them with get_prop_str, but unless you have the correct sizes, it would be easy to miss something. I thought propcase 9 (for propset 2, length 156 bytes) looked likely, because it is read and set in face detection related tasks. But after playing with it, I didn't see anything that clearly indicated if a face was detected. Also it (like most propcases) only seems to update on halfpress.
I'd attach the script I used, but I seem to have left the SD card with it at home.  I basically just looped through prop_id 1-500, stored the values in one array, and then looped through them again and compared each current value with the previous value, then printed the prop# and value if a change was detected.  I saw several prop_ids in the 200 range pop up, but they were all gibberish since I didn't have the lengths wrong.  I assumed the and incorrect length would just truncate, which doesn't seem to be the case, and they also don't seem to usually be printable characters either.  I really wish I had everything with me right now to reply properly!

Quote
There are some other large propcases that might be candidates, 0x70 (length 300 bytes) is also used in these tasks.

I've attached a list of all the propcase numbers and sizes I got from extracting all the propcase related calls I could find from the d10 firmware. This is a propset 2 camera, so should be applicable to your cameras if you want to look more.

The approach I'm looking into now is variables referenced by the face detection tasks. Unfortunately, canon didn't put many log messages in this area, so it's quite difficult to figure out what is going on. I've found at least 3 face detection related tasks:
FaceFrame
DispFace
ChaceFace

Where do you find these log messages?

Good news and bad news.

Good news: I'm pretty sure I've found a variable that stores the number of faces, in a structure shared by DispFace and ChaseFace.  On D10, this structure is at 0x193A4, and the face count is a 16 bit int at offset 0xC. This address is found at the start of ChaseFace.

This seems to run all the time, whether you are in face detect mode or not, and reacts quite quickly. The value updates both in plain live view and half press. It's even updated in MF :o

If you find the equivalent address on your cameras, it should be  trivial to write face detect script with this using peek, e.g:
Code: [Select]
face_count_addr=0x193b0
while peek(face_count_addr,2) < 1 do
sleep(10)
end
shoot()

Bad news: I don't see ChaseFace or DispFace in sx110. However, I do see some apparently face related debug strings that don't exist on d10:
Code: [Select]
ROM:FFDA5E38                 LDR     R6, =0x54D9C
ROM:FFDA5E3C                 ADR     R0, aDetectfaceinfo ; "\r\n  DetectFaceInfo#%u"
ROM:FFDA5E40                 LDRH    R1, [R6]
ROM:FFDA5E44                 BL      nullsub_218
ROM:FFDA5E48                 LDRH    R2, [R6,#4]
ROM:FFDA5E4C                 LDRH    R1, [R6,#2]
ROM:FFDA5E50                 ADR     R0, aHsizeUVsizeU ; "\r\n  Hsize = %u, Vsize = %u"
ROM:FFDA5E54                 BL      nullsub_218
ROM:FFDA5E58                 LDRH    R1, [R6,#6]
ROM:FFDA5E5C                 ADR     R0, aNum_of_resultU ; "\r\n  Num_Of_Result = %u"
ROM:FFDA5E60                 BL      nullsub_218
ROM:FFDA5E64                 LDRH    R1, [R6,#8]
ROM:FFDA5E68                 ADR     R0, aAll_num_of_res ; ", All_Num_Of_Result = %u"
ROM:FFDA5E6C                 BL      nullsub_218
ROM:FFDA5E70                 LDR     R1, [R6,#0xC]
ROM:FFDA5E74                 ADR     R0, aFsetframeinfoD ; "\r\n  fSetFrameInfo = %d"
ROM:FFDA5E78                 BL      nullsub_218
ROM:FFDA5E7C                 LDR     R1, [R6,#0x10]
ROM:FFDA5E80                 ADR     R0, aFexistprimaryf ; ", fExistPrimaryFace = %d"
If you use peek (or the memory browser and misc debug display) to look at the above offset from 0x54D9C, you may find something useful.

sd1000 looks to be different still...
That seems to be exactly what we're looking for!!  I will have to dig on both cameras to see if there are equivalents.  How did you figure out the memory address to look at?

*

Offline reyalp

  • ******
  • 10069
Re: Face Detect Trigger?
« Reply #16 on: 25 / June / 2012, 12:59:09 »
I'd attach the script I used, but I seem to have left the SD card with it at home.  I basically just looped through prop_id 1-500, stored the values in one array, and then looped through them again and compared each current value with the previous value, then printed the prop# and value if a change was detected.  I saw several prop_ids in the 200 range pop up, but they were all gibberish since I didn't have the lengths wrong.
My observation is that the canon firmware will truncate or pad with null bytes if the length is wrong. Propcase values are generally not readable strings, they are binary values that can be single bytes, 16 or 32 bit numbers etc. They can contain embedded nulls. Generally, you'd want to look at a hex dump of the value, unless you have some other information about how it should be interpreted.

I did most of my testing using chdkptp (shameless self promotion), like this:
!status,s=con:execwait([[return get_prop_str(9,0x9c)]]); print(util.hexdump(s))

For looking at memory values, you can use the rmem command, or send peek()

I find being able to interactively look at values like this from my PC very useful, compared to trying to do it with scripts uploaded to the camera or changing code, recompiling etc.
Quote
Quote
FaceFrame
DispFace
ChaceFace
Where do you find these log messages?
These are task names found in in disassembly of the firmware dump. I know they are task names because they are passed to one of the task creation functions. A task is like a process or thread on a PC.
Quote
That seems to be exactly what we're looking for!!  I will have to dig on both cameras to see if there are equivalents.  How did you figure out the memory address to look at?
Searching the firmware dump for strings containing "Face". The ROM:FFDA5E74 lines are the address in the dump.

For the SX110, you can look code quoted above and get some addresses to try with peek.
LDR     R6, =0x54D9C
gives you the starting address of the structure. The lines like
FFDA5E48                 LDRH    R2, [R6,#4]
gives you the offset into it. If the insturction is LDRH, that means it's a half word (16 bit int). A full 32 bit word be LDR, and a single byte would be LDRB. The equivalent of the above in lua would be
peek(0x54D9C+4,2)
The 2 tells peek to load a half word.
The string following the LDR instructions may give you some hint about the meaning of the value., e.g. Num_Of_Result = %u could be the number of faces ?
Don't forget what the H stands for.

*

Offline Naito

  • *
  • 19
Re: Face Detect Trigger?
« Reply #17 on: 25 / June / 2012, 16:13:23 »
Ah no wonder you know all these nooks and crannies.  I played with chdkptp on an earlier iteration of what I've been trying to write up, it's really neat!

Once I pick up the camera again I'll take a closer look and see if we can't figure this out.  It just seems like such an obvious and useful feature to have working!


*

Offline Naito

  • *
  • 19
Re: Face Detect Trigger?
« Reply #18 on: 02 / July / 2012, 09:30:51 »
SUCCESS on the SX110!!!

Quote
face_count_addr=0x54D9C
repeat
print(peek(face_count_addr+6,2))
sleep(100)
until false

That gave me the count of faces detected on the SX110!!

Thank you Reyalp!!  This will make the photobooth script I've been working on much more reliable!!

SD1000 seems to use a different address, but I think you found the strings we need to look for.  Would be fantastic to generalize it and put it in the main CHDK build!
« Last Edit: 02 / July / 2012, 09:35:30 by Naito »

*

Offline reyalp

  • ******
  • 10069
Re: Face Detect Trigger?
« Reply #19 on: 02 / July / 2012, 17:21:08 »
SUCCESS on the SX110!!!
Quote
face_count_addr=0x54D9C
repeat
print(peek(face_count_addr+6,2))
sleep(100)
until false
That gave me the count of faces detected on the SX110!!
Glad to hear it. Have you tested when it updates, e.g. continuously when live view is on, only in halfpress, outside of halfpress ?

Quote
SD1000 seems to use a different address, but I think you found the strings we need to look for.
The SD1000 didn't seem to have the same strings. It's also digic III, but it's a vxworks camera.

Quote
  Would be fantastic to generalize it and put it in the main CHDK build!
This may be tricky. It should fairly straightforward to use the sigfinder to get the right address for cameras like sx110, since the variable is directly referenced from a string. The others may be a bit more complicated. In any case, we could add it over time, it has to be a camera dependent feature anyway since not all cameras have face detect at all.
Don't forget what the H stands for.

 

Related Topics