News:

2023-03-15 Major improvements to the new Geolocation feature

Main Menu

PersonInImage to ACDsee

Started by mulu, January 13, 2020, 09:47:03 PM

Previous topic - Next topic

mulu

My current software stores people tags in XMP-iptcExt:PersonInImage. The software ACDsee does not recognize this tag so I need to somehow translate that into their custom tags. So I have something like:

XMP-iptcExt:PersonInImage = John Doe*Mike Miller*Jane Doe

which needs to be moved to

XMP-acdsee-rs:RegionsRegionListName = John Doe
XMP-acdsee-rs:RegionsRegionListType = Face
XMP-acdsee-rs:RegionsRegionListName = Mike Miller
XMP-acdsee-rs:RegionsRegionListType = Face
XMP-acdsee-rs:RegionsRegionListName = Jane Doe
XMP-acdsee-rs:RegionsRegionListType = Face

I think this can be done with:

"exiftool(-k).exe" -RegionsRegionListName+="John Doe" [ImageName].jpg
"exiftool(-k).exe" -RegionsRegionListType+="Face" [ImageName].jpg
"exiftool(-k).exe" -RegionsRegionListName+="Mike Miller" [ImageName].jpg
"exiftool(-k).exe" -RegionsRegionListType+="Face" [ImageName].jpg
"exiftool(-k).exe" -RegionsRegionListName+="Jane Doe" [ImageName].jpg
"exiftool(-k).exe" -RegionsRegionListType+="Face" [ImageName].jpg

However, I am getting the error Tag RegionsRegionListName is not defined. Reading the forums it seems that's because exiftool doesn't know how to write the tags (it reads them just fine). I found a link that explains how to add support for a tag, i.e. https://exiftool.org/config.html However, I am kind of stomped what to do here. I think it's something like what I list below but what is the ????

%Image::ExifTool::UserDefined = (
    # XMP tags may be added to existing namespaces:
    'Image::ExifTool::XMP::acdsee-rs' => {
        # Example 5.  XMP-acdsee-rs:RegionsRegionListName
        RegionsRegionListName => { ???? },
        RegionsRegionListType => { ???? }
    }
}

StarGeek

After a quick google search it looks like it won't be a simple thing to create tags for this as the two tags you list appear to be part of a Structured tag, similar to the MWG Regions Tags, the Microsoft region tags, and the IPTC region tags.  It's more than just a name and face definition, it includes location and dimensions of the region on the image, with the possibility of multiple entries of that info.

Phil has just gone (or is going) on vacation so it may be a bit before he can look at this. 

If you can post an example image that has one or two faces already the other region tags set (Regions Applied To Dimensions H, Regions Applied To Dimensions W, Regions Region List DLY Area H, Regions Region List DLY Area W, etc) I'll see what I can do.  This isn't my area of expertise but I'd like to try and puzzle it out.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

mulu

Thanks for the quick response. I got an image from parkinson.org and added people using both my current program and ACDsee. The current program stores the names in XMP-expressionmedia:People, XMP-mediapro:People and XMP-iptcExt:PersonInImage.

ACDsee stores the people in XMP-acdsee-rs. All 5 faces were recognized with the face recognition algorithm. However, I deleted to of the automatically recognized faces and then added them manually. I did this because the faces that are recognized automatically have additional tags that the manually added faces don't have.

My idea was to first check if I can just add people with the two tags RegionsRegionListName and RegionsRegionListType. If ACDsee doesn't recognize those, then I was going to add RegionsRegionListDLYAreaH/W/X/Y with some fixed values just so I have something even if the position of the face is incorrect. The point is that I simply want to transfer the people I already identified/tagged in my old software will be recognized by the new software.

StarGeek

Useful choice of image, lots of faces to play with.  It does lead to some questions, though.  The faces labeled Austin Powers, Jane Doe, and Mini Me have Region List DLY Area and Region List ALG Area, while the John Doe and Mike Miller faces only have Region List DLY Area.  And the X coordinate is the same but the height/width and Y coordinates differ between the DLY and ALG regions.

As a followup, I've removed the face/name data you added, rotated the image and set the EXIF:Orientation tag so that it displays correctly.  Can you grab the attached image and apply the same names/regions to this one?  I want to see how ACDsee handles regions in rotated images.

I'm going to work on this tomorrow, see how well I can do with it.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

mulu

I downloaded the image and loaded it into ACDsee. Please note that both Windows and ACDsee still show the image in landscape, i.e. it is not rotated. ACDsee recognized all 5 faces. Just like before I deleted the auto detected faces of the 3rd (John Doe) and 5th (Mike Miller) person counting from the left side. Then I added those faces manually.

The faces that are detected automatically have the ALG area (not sure what that is) and the DLY area while the manually added faces only have the DLY area. The RegionsRegionListNameAssignType indicated if ACDsee automatically assign a name to a face (based on other photos) or if the user entered the name manually.

Note that the image I sent previously was too large to upload so I had to downscale it which I did in ACDsee. Maybe this did mess up the coordinates/size. I did however change the name of one face, saved the meta data to the file, changed the name back and saved the meta data to the file again. I did this so that the XMP-acdsee-rs section was recreated and hopefully then used the correct coordinates/sizes.

StarGeek

Quote from: mulu on January 14, 2020, 01:09:11 AM
I downloaded the image and loaded it into ACDsee. Please note that both Windows and ACDsee still show the image in landscape, i.e. it is not rotated.

Yes, this is the situation I was hoping to test.  The image has been rotated 90° clockwise and the EXIF:Orientation has been set to indicate that that to orientate the image correctly, it needs to be rotated another 270° clockwise.  If you want to see how the image really looks, go to Tools->Options in ACDSee, click General, and unselect "Automatically rotate JPEG and TIFF images based on EXIF orientation" and reload it.

I wanted to see if ACDSee would properly handle the location of a region in cases where the image was rotated.  I know that the MWG regions specifically address this and the Microsoft regions do not.

QuoteThe faces that are detected automatically have the ALG area (not sure what that is) and the DLY area while the manually added faces only have the DLY area. The RegionsRegionListNameAssignType indicated if ACDsee automatically assign a name to a face (based on other photos) or if the user entered the name manually.

Ah, excellent.  This is info I was really curious about.

QuoteNote that the image I sent previously was too large to upload so I had to downscale it which I did in ACDsee. Maybe this did mess up the coordinates/size.

No, it didn't.  That's the beauty of the way this region system (and the other region types) work.  They don't give exact pixel coordinates.  They show it as a percent of the image size.  For example, here's the data for John Doe
{DLYArea=
{H=0.207815,W=0.111308,X=0.500888,Y=0.178508},
Name=John Doe,
Type=Face},

The Width is 1024*0.111308=113.9 (round it to 114), the Height is 683*0.207815=141.9 (round it to 142), X is 1024*0.500888=512.9 (513) and Y is 683*0.178508=121.9 (122).  Now, if you increase/decrease the size of the image, the actual numbers will change, but it will still be the same position.

The one thing to figure out is where the X/Y is in relation to the region.  In the MWG regions, for example, the X/Y coordinates are the center of the image and the Width/Height are the distance from that center point to either side of the regions, so the Width/Height numbers are half the actual size of the region.  If I recall correctly, in the Microsoft regions, the X/Y is the top left of the region and the Width/Height are the full size of the region and measured from that top left point.

Just a bit of a warning, I'm using this as a learning experience so I may not be all that quick on working on this.  At the very least, if I'm not done by the 24th or so, Phil will be back and he'll probably be able to whip up a real solution in 5-10 minutes.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

mulu

Thanks a lot for looking into this. I have a couple of weeks left to cancel the purchase of ACDsee but I hope I can actually transfer my image 'catalog' to ACDsee.

StarGeek

Just an update to let you know I haven't ignored this.  This is going to be long, so hang in there.

I've got pretty much all the pieces for creating the ACDSee structured tag, but just haven't figured out how to put it together properly.  I'll list everything here so it can be sort of a tutorial on how to figure this out and, if I don't get it together before Phil gets back, he'll have most of the work done if he wants to step in and finish it off in a few minutes.

First, the basic structure of the tag.  Looking at the XMP (see below), the relevant data is called Regions.  You can extract this by this command without need of a config file:
exiftool -struct -regions <file.jpg>

The output of the example image above is this:
---- XMP-acdsee-rs ----
Regions                         : {AppliedToDimensions={H=683,Unit=pixel,W=1024},RegionList=[{ALGArea={H=0.189286,W=0.126190,X=0.291964,Y=0.153348},DLYArea={H=0.194964,W=0.107262,X=0.291964,Y=0.156188},Name=Austin Powers,NameAssignType=manual,Type=Face},{ALGArea={H=0.184821,W=0.123214,X=0.588839,Y=0.384598},DLYArea={H=0.190366,W=0.104732,X=0.588839,Y=0.387371},Name=Jane Doe,NameAssignType=manual,Type=Face},{ALGArea={H=0.188839,W=0.125893,X=0.418155,Y=0.323661},DLYArea={H=0.194504,W=0.107009,X=0.418155,Y=0.326493},Name=Mini Me,NameAssignType=manual,Type=Face},{DLYArea={H=0.207815,W=0.111308,X=0.500888,Y=0.178508},Name=John Doe,Type=Face},{DLYArea={H=0.261101,W=0.148017,X=0.744227,Y=0.279751},Name=Mike Miller,Type=Face}]}


I'll break it down and trim it to only show one of the faces, so as to get an idea of what's happening
{
AppliedToDimensions={
H=683,
Unit=pixel,
W=1024
},
RegionList=[
{
ALGArea={
H=0.189286,
W=0.126190,
X=0.291964,
Y=0.153348
},
DLYArea={
H=0.194964,
W=0.107262,
X=0.291964,
Y=0.156188
},
Name=Austin Powers,
NameAssignType=manual,
Type=Face
}
]
}


Every entry between the braces is a KEY=VALUE pairing.  In perl, this is represented as a hash.  The brackets after RegionList indicates an array.  This is where each individual face region is placed, enclosed in braces.

Here is the matching part of the embedded XMP, edited to show the important parts
  <rdf:Description rdf:about=""
    xmlns:acdsee-rs="http://ns.acdsee.com/regions/"
    xmlns:acdsee-stDim="http://ns.acdsee.com/sType/Dimensions#"
    xmlns:acdsee-stArea="http://ns.acdsee.com/sType/Area#">

   <acdsee-rs:Regions rdf:parseType="Resource">
    <acdsee-rs:AppliedToDimensions rdf:parseType="Resource">
     <acdsee-stDim:h>683</acdsee-stDim:h>
     <acdsee-stDim:unit>pixel</acdsee-stDim:unit>
     <acdsee-stDim:w>1024</acdsee-stDim:w>
    </acdsee-rs:AppliedToDimensions>
    <acdsee-rs:RegionList>
     <rdf:Bag>
      <rdf:li rdf:parseType="Resource">
       <acdsee-rs:DLYArea rdf:parseType="Resource">
        <acdsee-stArea:h>0.194964</acdsee-stArea:h>
        <acdsee-stArea:w>0.107262</acdsee-stArea:w>
        <acdsee-stArea:x>0.291964</acdsee-stArea:x>
        <acdsee-stArea:y>0.156188</acdsee-stArea:y>
       </acdsee-rs:DLYArea>
       <acdsee-rs:ALGArea rdf:parseType="Resource">
        <acdsee-stArea:h>0.189286</acdsee-stArea:h>
        <acdsee-stArea:w>0.126190</acdsee-stArea:w>
        <acdsee-stArea:x>0.291964</acdsee-stArea:x>
        <acdsee-stArea:y>0.153348</acdsee-stArea:y>
       </acdsee-rs:ALGArea>
       <acdsee-rs:Name>Austin Powers</acdsee-rs:Name>
       <acdsee-rs:Type>Face</acdsee-rs:Type>
       <acdsee-rs:NameAssignType>manual</acdsee-rs:NameAssignType>
      </rdf:li>
     </rdf:Bag>
    </acdsee-rs:RegionList>
   </acdsee-rs:Regions>
  </rdf:Description>
</rdf:RDF>
</x:xmpmeta>


This structured tag is extremely similar to the MWG Regions tag.  Pretty close to a copy paste with a couple of edits.  Phil's note under the ACDSee tags really applies here.

There are a total of three structures which make up the entire tag structure.  The AppliedToDimensions structure, the ALGArea/DLYArea structure (each uses the same structure), and the RegionList structure.

First, I'll start off with a template created by extracting the necessary items from the example_config file.  It needs the "new XMP namespaces" example and a matching "structured XMP tag" example.  Putting these together creates the following

%Image::ExifTool::UserDefined = (
    'Image::ExifTool::XMP::Main' => {
        # namespace definition for examples 8 to 11
        xxx => { # <-- must be the same as the NAMESPACE prefix
            SubDirectory => {
                TagTable => 'Image::ExifTool::UserDefined::xxx',
                # (see the definition of this table below)
            },
        },
    },
);

Tool family 1 group name of 'XMP-xxx'.
%Image::ExifTool::UserDefined::xxx = (
    GROUPS => { 0 => 'XMP', 1 => 'XMP-xxx', 2 => 'Image' },
    NAMESPACE => { 'xxx' => 'http://ns.myname.com/xxx/1.0/' },
    WRITABLE => 'string', # (default to string-type tags)
    # Example 11.  XMP-xxx:NewXMPxxxStruct (a structured tag)
    # - example structured XMP tag
    NewXMPxxxStruct => {
        # the "Struct" entry defines the structure fields
        Struct => {
            # optional namespace prefix and URI for structure fields
            # (required only if different than NAMESPACE above)
            # --> multiple entries may exist in this namespace lookup,
            # with the last one alphabetically being the default for
            # the fields, but each field may have a "Namespace"
            # element to specify which prefix to use
            NAMESPACE => { 'test' => 'http://x.y.z/test/' },
            # optional structure name (used for warning messages only)
            STRUCT_NAME => 'MyStruct',
            # optional rdf:type property for the structure
            TYPE => 'http://x.y.z/test/xystruct',
            # structure fields (very similar to tag definitions)
            X => { Writable => 'integer' },
            Y => { Writable => 'integer' },
            # a nested structure...
            Things => {
                List => 'Bag',
                Struct => {
                    NAMESPACE => { thing => 'http://x.y.z/thing/' },
                    What  => { },
                    Where => { },
                },
            },
        },
        List => 'Seq', # structures may also be elements of a list
    },
    # Each field in the structure has a corresponding flattened tag that is
    # generated automatically with an ID made from a concatenation of the
    # original structure tag ID and the field name (after capitalizing the
    # first letter of the field name if necessary).  The Name and/or
    # Description of these flattened tags may be changed if desired, but all
    # other tag properties are taken from the structure field definition.
    # The "Flat" flag must be used when setting the Name or Description of a
    # flattened tag.  For example:
    NewXMPxxxStructX => { Name => 'SomeOtherName', Flat => 1 },
);


Next, creating the structures.  The AppliedToDimensions is easy.  It's basically a copy of the sDimensions structure used by the MWG Regions and found in the XMP.pm file.  So it can basically be copy/pasted, but requires some edits.  First, the structure needs to be renamed so it doesn't collide with the MWG structure.  I'll keep the same naming format, just add in the ACDSee.  Then the NAMESPACE needs editing.  Looking at the XML for this part shows the namespace is acdsee-stDim, which goes back to the URI at the top of the XML.  Using the example_config, it looks like the correct entry would be a hash of acdsee-stDim and the URI above.  The final result is this.

%sACDSeeDimensions = (
    STRUCT_NAME => 'Dimensions',
    NAMESPACE   => {'acdsee-stDim' => 'http://ns.acdsee.com/sType/Dimensions#'},
    w           => { Writable => 'real' },
    h           => { Writable => 'real' },
    unit        => { },
);


Next, the area structure used by ALGArea/DLYArea.  Again, pretty much a copy/paste of the MWG sArea , missing the D and Unit entries.   I just realized I have no idea what the D entry is in the MWG.  Keeping with the same pattern, add ACDSee the name and change the namespace, taken directly from the XMP.

my %sACDSeeArea = (
    STRUCT_NAME => 'Area',
NAMESPACE => { 'acdsee-stArea' => 'http://ns.acdsee.com/sType/Area#' },
   'x'          => { Writable => 'real' },
   'y'          => { Writable => 'real' },
    w           => { Writable => 'real' },
    h           => { Writable => 'real' },
);


The final structure is for the region list.  It is similar to the MWG Region list, but has more changes.  This part will be repeated once for every region defined.  So, here are the edits line by line from the linked MWG structure. 

  • First, the name needs to be changed so as not to overlap the MWG structure name.  Simply add ACDSee to the name give sACDSeeRegionStruct.
  • Change the MWG RegionStruct to ACDSee Regions.
  • The NAMESPACE taken from the XMP is acdsee-rs with an URI of http://ns.acdsee.com/regions/.
  • Next is Area.  Here's a big change in the ACDSee version.  It has two areas, ALGArea, which appears to be the area selected by ACDSee's facial recognition and does not appear when a face is manually added, and the DLYArea, which seems to appear with both the detected and manually added regions.  So Area is changed to each of those names and then points the the above sACDSeeArea structure.
  • Next is Type.  The ACDSee type might have limited options, but without further research, I don't know what those might be, so I'll change it to { } which will accept any string value.  If new info is discovered, then a PrintConv might be necessary.
  • Name is the same, so no change.
  • The rest of the MWG entries (Description, FocusUsage, BarCodeValue, Extensions, Rotation) don't apply as they aren't seen in the example I have, so they are deleted.
  • Then a new entry for NameAssignType is added.  This might be similar to Type and have limited option, but for now, I'll leave it as a simple string.
  • I think seeAlso is an exiftool entry which probably doesn't apply here so it's removed.
The resulting structure is as follows

my %sACDSeeRegionStruct = (
STRUCT_NAME => 'ACDSee Regions',
NAMESPACE => 'acdsee-rs',
ALGArea => {Struct => %sACDSeeArea },
DLYArea => {Struct => %sACDSeeArea },
Name => { },
NameAssignType => { },
Type => { },
);


Now to skip back to the template taken from the example_config and try to put this all together.  The first part of the template will insert our new structure into the main XMP table.  The xxx needs to be changed to the same prefix as the NAMESPACE for the tag, which would be acdsee-rs.  The second xxx needs to point to the second part of the template.  Again, I'll just add ACDSee to the title.

%Image::ExifTool::UserDefined = (
# new XMP namespaces (eg. xxx) must be added to the Main XMP table:
'Image::ExifTool::XMP::Main' => {
acdsee-rs => { # <-- must be the same as the NAMESPACE prefix
SubDirectory => { TagTable => 'Image::ExifTool::UserDefined::ACDSeeRegions' },
},
},
);


Now for the final part, again going line by line.  This part is the most complex and I'll be looking at the MWG Regions and Microsoft Regions definitions for guidence.

  • Change the xxx to the name given above, ACDSeeRegions.
  • In GROUPS, it should be considered part of the XMP-acdsee group, so change XMP-xxx to XMP-acdsee.
  • In NAMESPACE, change xxx and the URI to acdsee-rs and http://ns.acdsee.com/regions/.
  • Leave WRITABLE alone, as a string is probably the best for a default.
  • The original command to get the structure used Regions as the name and that's what is in the XMP, so NewXMPxxxStruct will be changed to Regions.
  • Next, going by the MWG/MP regions, I'll add a name for the structure.  Keeping in similar to the other two, it'll be called RegionInfoACDSee.
  • The other two structures have name entries for flattened tags, but since I'm unsure of the details for that, I won't worry about those yet.
  • According to the notes in the example config, I shouldn't need a new NAMESPACE.  I'll edit it but comment it out for now.
  • The struture name used for warnings will be similar to the other regions with ACDSee in the name.
  • Most of the rest of the example doesn't seem to apply, but the MWG structure seems to be what is needed.  Basically a copy paste from there.
  • RegionList is the same as in the original XMP.
  • Commenting FlatName for now.
  • The next Struct needs to point to the sACDSeeRegions.
  • Same with AppliedToDimensions.

%Image::ExifTool::UserDefined::ACDSeeRegions = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-acdsee ', 2 => 'Image' },
NAMESPACE => { 'acdsee-rs' => 'http://ns.acdsee.com/regions/' },
WRITABLE => 'string', # (default to string-type tags)
Regions => {
Name => 'RegionInfoACDSee',
# the "Struct" entry defines the structure fields
Struct => {
# NAMESPACE => { 'acdsee-rs' => 'http://ns.acdsee.com/regions/' },
# optional structure name (used for warning messages only)
STRUCT_NAME => 'ACDSee RegionInfo',       
RegionList => {
FlatName => 'Region',
Struct => \%sACDSeeRegionStruct,
List => 'Bag',
},
AppliedToDimensions => { Struct => \%sACDSeeDimensions },
},
},
);


Putting it all together gives this config file:
%sACDSeeDimensions = (
    STRUCT_NAME => 'Dimensions',
    NAMESPACE   => {'acdsee-stDim' => 'http://ns.acdsee.com/sType/Dimensions#'},
    w           => { Writable => 'real' },
    h           => { Writable => 'real' },
    unit        => { },
);

my %sACDSeeArea = (
    STRUCT_NAME => 'Area',
NAMESPACE => { 'acdsee-stArea' => 'http://ns.acdsee.com/sType/Area#' },
   'x'          => { Writable => 'real' },
   'y'          => { Writable => 'real' },
    w           => { Writable => 'real' },
    h           => { Writable => 'real' },
);

my %sACDSeeRegionStruct = (
STRUCT_NAME => 'ACDSee Regions',
NAMESPACE => 'acdsee-rs',
ALGArea => {Struct => %sACDSeeArea },
DLYArea => {Struct => %sACDSeeArea },
Name => { },
NameAssignType => { },
Type => { },
);

%Image::ExifTool::UserDefined = (
# new XMP namespaces (eg. xxx) must be added to the Main XMP table:
'Image::ExifTool::XMP::Main' => {
acdsee-rs => { # <-- must be the same as the NAMESPACE prefix
SubDirectory => { TagTable => 'Image::ExifTool::UserDefined::ACDSeeRegions' },
},
},
);

%Image::ExifTool::UserDefined::ACDSeeRegions = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-acdsee ', 2 => 'Image' },
NAMESPACE => { 'acdsee-rs' => 'http://ns.acdsee.com/regions/' },
WRITABLE => 'string', # (default to string-type tags)
Regions => {
Name => 'RegionInfoACDSee',
# the "Struct" entry defines the structure fields
Struct => {
# NAMESPACE => { 'acdsee-rs' => 'http://ns.acdsee.com/regions/' },
# optional structure name (used for warning messages only)
STRUCT_NAME => 'ACDSee RegionInfo',       
RegionList => {
#FlatName => 'Region',
Struct => \%sACDSeeRegionStruct,
List => 'Bag',
},
AppliedToDimensions => { Struct => \%sACDSeeDimensions },
},
},
);
#------------------------------------------------------------------------------
1;  #end


Unfortunately, testing it by either writing the original structure to another file or listing the region data properly doesn't quite work yet.  There's something I'm missing to get output the same as with the MWG or MP regions.  Also, I'm getting a No definition for structure 'w' error, so something is wrong.

I'm a little burned out from all the editing of this post, so I'll try and fix it tomorrow.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

mulu

Wow, that was quite some work. Thanks. I read the entire post. While I can see what you are doing, i.e. defining all the different structures, different level (with the region array), etc it's kind of over my head. The only 'structure' w I see is

w           => { Writable => 'real' },

I wonder if the w line and h line are interchanged if it then reports that structure h is not defined. If so then there seems to be something wrong with the definition. Maybe something is incorrect with the Writable => 'real'?

StarGeek

It's not just the w.  The item that is wrong changes with each run.  That's because the structure is a perl hash and you can't depend upon the order of a perl hash.  There's something fundamentally wrong in that code because sometimes the error is one of the exiftool items like NAMESPACE.

There are two errors in that that I haven't taken time to fix in that post.  The first is at the very start.  sACDSeeDimensions isn't declared, it needs a my in front of it.

The second is this line
GROUPS => { 0 => 'XMP', 1 => 'XMP-acdsee ', 2 => 'Image' },
There's an extra space after XMP-acdsee which needs to be removed.

But even though I corrected those errors, there's still a problem someplace. 

Anyway, Phil will be back in just a few more days in case I don't figure it out.  Though he'll probably look at that post and think "what the bloody hell happens when I'm gone"   :D
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

mulu

#10
Well, that shows I don't really know what I am talking about... I did go through the examples for the command line examples. While I can write simple tags how would I write something as complicated as those ACDsee tags?

Edit:
Ah, I found and example in a different post:

exiftool -regionlist+="{Area= {H=0.2,Unit=normalize,W=0.2,X=0.5,Y=0.5},Name=Joe,Type=Face}" pic.jpg

I need to try this with the ACDsee structure.

mulu

Do you know if Phil is reading this forum and will check what you have accomplished so far?

Phil Harvey

I've seen this thread but I don't know if I have much to contribute here.  Is there an ExifTool question that needs to be answered?  I don't have time right now to read the whole thread.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

StarGeek

To summarize my crazy long post

I attempted to make a config file to read/write ACDSee regions, documenting what I did as I go.  Unfortunately, it fails badly.  A lot of copy/pasting from other region configs.  This is the result
my %sACDSeeDimensions = (
    STRUCT_NAME => 'ACDSee Dimensions',
    NAMESPACE   => {'acdsee-stDim' => 'http://ns.acdsee.com/sType/Dimensions#'},
    'w'           => { Writable => 'real' },
    'h'           => { Writable => 'real' },
    'unit'        => { },
);

my %sACDSeeArea = (
    STRUCT_NAME => 'ACDSee Area',
NAMESPACE => { 'acdsee-stArea' => 'http://ns.acdsee.com/sType/Area#' },
'x' => { Writable => 'real' },
'y' => { Writable => 'real' },
w => { Writable => 'real' },
h => { Writable => 'real' },
);

my %sACDSeeRegionStruct = (
STRUCT_NAME => 'ACDSee Regions',
NAMESPACE => { 'acdsee-rs' => 'http://ns.acdsee.com/regions/' },
ALGArea => {Struct => %sACDSeeArea },
DLYArea => {Struct => %sACDSeeArea },
Name => { },
NameAssignType => { },
Type => { },
);

%Image::ExifTool::UserDefined = (
# new XMP namespaces (eg. xxx) must be added to the Main XMP table:
'Image::ExifTool::XMP::Main' => {
acdsee-rs => { # <-- must be the same as the NAMESPACE prefix
SubDirectory => {
TagTable => 'Image::ExifTool::UserDefined::ACDSeeRegions'
},
},
},
);

%Image::ExifTool::UserDefined::ACDSeeRegions = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-acdsee', 2 => 'Image' },
NAMESPACE => { 'acdsee-rs' => 'http://ns.acdsee.com/regions/' },
WRITABLE => 'string', # (default to string-type tags)
Regions => {
Name => 'RegionInfoACDSee',
# the "Struct" entry defines the structure fields
Struct => {
# NAMESPACE => { 'acdsee-rs' => 'http://ns.acdsee.com/regions/' },
# optional structure name (used for warning messages only)
STRUCT_NAME => 'ACDSee RegionInfo',       
RegionList => {
#FlatName => 'Region',
Struct => \%sACDSeeRegionStruct,
List => 'Bag',
},
AppliedToDimensions => { Struct => \%sACDSeeDimensions },
},
},
);
#------------------------------------------------------------------------------
1;  #end


You can find an example image in this post.

The xmp seemed to me to be very similar to the MWG regions code.  Though it can have two areas defined.  Manually added regions only have the DLYArea structure.  Regions created by ACDSees facial recognition have the DLYArea and an ALGArea. 

I've messed with it, probably made it worse, and just couldn't get it to work.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

You were very close.  The only changes I made were:

<     ALGArea         => {Struct => %sACDSeeArea },
<     DLYArea         => {Struct => %sACDSeeArea },
---
>     ALGArea         => { Struct => \%sACDSeeArea },
>     DLYArea         => { Struct => \%sACDSeeArea },
31c31
<         acdsee-rs => { # <-- must be the same as the NAMESPACE prefix
---
>         'acdsee-rs' => { # <-- must be the same as the NAMESPACE prefix
40c40
<     GROUPS => { 0 => 'XMP', 1 => 'XMP-acdsee', 2 => 'Image' },
---
>     GROUPS => { 0 => 'XMP', 1 => 'XMP-acdsee-rs', 2 => 'Image' },


Attached is the config file that works for me with this command:

exiftool -config acdsee-rs.config -xmp-acdsee-rs:RegionInfoACDSee="{AppliedToDimensions={H=683,Unit=pixel,W=1024},RegionList=[{ALGArea={H=0.189286,W=0.126190,X=0.291964,Y=0.153348},DLYArea={H=0.194964,W=0.107262,X=0.291964,Y=0.156188},Name=Austin Powers,NameAssignType=manual,Type=Face},{ALGArea={H=0.184821,W=0.123214,X=0.588839,Y=0.384598},DLYArea={H=0.190366,W=0.104732,X=0.588839,Y=0.387371},Name=Jane Doe,NameAssignType=manual,Type=Face},{ALGArea={H=0.188839,W=0.125893,X=0.418155,Y=0.323661},DLYArea={H=0.194504,W=0.107009,X=0.418155,Y=0.326493},Name=Mini Me,NameAssignType=manual,Type=Face},{DLYArea={H=0.207815,W=0.111308,X=0.500888,Y=0.178508},Name=John Doe,Type=Face},{DLYArea={H=0.261101,W=0.148017,X=0.744227,Y=0.279751},Name=Mike Miller,Type=Face}]}" test.xmp

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).