Scripts for detecting and fixing orphan area tags

vlad
Posts: 895
Joined: 01 Sep 08 15:20

Scripts for detecting and fixing orphan area tags

Post by vlad » 02 Apr 15 10:40

Following a request from Luc and some digging into the scripting API (which is not always easy and fun, btw), I have written and attached here two scripts for detecting and fixing images with orphan area tags (captions). For the purpose of these scripts, an orphan area tag is any area caption which occurs in an image that does not have a corresponding label assigned. For example, if an image contains a face area tagged as 'John', but the image has not been assigned the 'John' label (whether that exists or not in the catalog), then that image (along with the corresponding area) qualifies as an image (area) with an orphan tag.

Filter With Orphan Area Tags simply filters all images with at least one orphan area tag. It does not take any action or display any information.

Assign Labels for Orphan Area Tags does two things, on a selection of images (possibly collected by the first script): it detects all areas with orphan tags (which may possibly include multiple areas in the same image) and it automatically fixes the orphan tags. Specifically, it takes the following actions for each orphan area tag:
1. If a catalog label matching the area caption already exists in the catalog, then it simply assigns it to the image. (Please note that the script simply assigns the (first) label returned by the API - no checks or preferences are currently implemented for the case when multiple labels with the same name are defined in the catalog.)
2. If no catalog label matching the area caption already exists in the catalog, then it creates a new one (e.g., 'John') right under the People category. (Please note that if you would like to change this default category, you may simply replace the two occurences of 'People' in the code with your prefrred category name - it may even be a new category, that will be created on demand by the script. You could even specify a parent label rather than a top-level category, but that would require slightly more tweaks.)

Upon completion, the script reports how many labels it assigned (= how many orphan area tags were found), how many of those labels were newly created (if any) and how many images were fixed (got new assignments).

I hope the scripts are helpful, at least for Luc.
Attachments
Filter With Orphan Area Tags.psc
Filters images with orphan area tags.
(1.69 KiB) Downloaded 150 times
Assign Labels for Orphan Area Tags.psc
Assigns labels corresponding to orphan area tags.
(4.39 KiB) Downloaded 138 times

LucLL
Posts: 33
Joined: 20 Feb 15 19:02

Re: Scripts for detecting and fixing orphan area tags

Post by LucLL » 06 Apr 15 15:35

Hi Vlad,

Amazing that you have developed this. I will right away give it a try and let you know how it works out. Thanks again very much for the effort you put into this. If you would be around in Prague ro wherever we meet I do owe you more than a few beers :-)

LucLL
Posts: 33
Joined: 20 Feb 15 19:02

Re: Scripts for detecting and fixing orphan area tags

Post by LucLL » 06 Apr 15 16:37

Hi Vlad,
The select seems to be working but I have an issue with the Assign Labels one.
When I run that one I get the error Unknown identifier or variable is not declared"... (see attached)
The select is anyway already helpful :)
Cheers, Luc
Attachments
Screen Shot 2015-04-06 at 17.28.17.png
Screen Shot 2015-04-06 at 17.28.17.png (59.97 KiB) Viewed 6369 times

vlad
Posts: 895
Joined: 01 Sep 08 15:20

Re: Scripts for detecting and fixing orphan area tags

Post by vlad » 06 Apr 15 19:13

Hi Luc,
If you would be around in Prague ro wherever we meet I do owe you more than a few beers :-)
Ah, Prague: beautiful place! (There are several years since I visited it, so a new visit is indeed in order.) And it's really funny, 'cause just a couple of days ago I drank Staropramen beer, which (I think) is made in Prague! No kidding.
The select seems to be working but I have an issue with the Assign Labels one.
When I run that one I get the error Unknown identifier or variable is not declared"
That's strange, since there is not even an occurrence of 'Selected' at line 38: the first occurrence is at line 40. Did you change anything (perhaps accidentally) in the script, by any chance? If yes, then could you please download and try again the script? If not, could you provide more info (build number, how do you run the script, is any selection made etc.)?

Cheers,
Vlad

LucLL
Posts: 33
Joined: 20 Feb 15 19:02

Re: Scripts for detecting and fixing orphan area tags

Post by LucLL » 06 Apr 15 21:06

Hi Vlad,

I didn't change anything, but I can try to download it again and see if there is any difference.

I went to the catalog by date and selected a year and then selected all the images and in the filter bar selected your filter. I get then immediately this error. Each time the same. Also if I first ran the other script to select the orphaned ones.

I'm on build 3.1.0.2067.pg

Regards,
Luc

DirkS
moderator
Posts: 284
Joined: 25 May 08 14:28
Location: Essex, UK

Re: Scripts for detecting and fixing orphan area tags

Post by DirkS » 06 Apr 15 21:27

LucLL wrote: in the filter bar selected your filter. I get then immediately this error. Each time the same. Also if I first ran the other script to select the orphaned ones
The 'Assign...' script is not a filter script. You run it by opening the Scripter (Tools menu) then open + run the script file from there.
Problems searching the forum? Try Google Site Search by adding 'site:forum.idimager.com' to a standard Google search.

LucLL
Posts: 33
Joined: 20 Feb 15 19:02

Re: Scripts for detecting and fixing orphan area tags

Post by LucLL » 06 Apr 15 23:16

Hi DirkS,
Well... learned something new again .... yep, if i run it properly :-) it works :-)
Thanks for clarifying, much appreciated!

Vlad,
Thanks again, works like a charm!

Regards,
Luc

vlad
Posts: 895
Joined: 01 Sep 08 15:20

Re: Scripts for detecting and fixing orphan area tags

Post by vlad » 07 Apr 15 8:44

Luc, you are welcome - I'm glad I could help.

vlad
Posts: 895
Joined: 01 Sep 08 15:20

Re: Scripts for detecting and fixing orphan area tags

Post by vlad » 10 Feb 16 0:59

My apologies - I have never submitted my scripts to the resource repository, where they naturally belong. Since forum attachments are currently disabled, I am going to copy the script contents over the next two posts, for whoever is still interested in running those scripts.

vlad
Posts: 895
Joined: 01 Sep 08 15:20

Re: Scripts for detecting and fixing orphan area tags

Post by vlad » 10 Feb 16 1:03

Filter With Orphan Area Tags.psc:

Code: Select all

(*
  Author:  Vlad
  Version: 1.1
  Description:
        This script filters all images with orphan area tags.
        (Orphan area tag = an area caption which does not have a corresponding label assignment)
*)

function areaHasMatchingLabel(AARea: TCatalogArea;
                              AItem: TImageItem)  : Boolean;
begin
    result := false;
    if (AArea.Caption = '') then   // no caption found
        result:= true;
    else
    begin
        AProps := TCatalogItemProps.Create (TCatalogItemProp, '');
        Catalog.EnumPropsForImage (AItem, AProps, false, true);
        for j := 0 to AProps.Count-1 do
        begin
            if (AProps.Items[j].PropName = AArea.Caption) then  // matching label found - no need to check other labels
            begin
                result := true;
                break;
            end;
        end;
        AProps.Free;
    end;
end;


function Filter(AItem: TImageItem): Boolean;
var
    AProps: TCatalogItemProps;
    AAreas: TCatalogAreas;
begin
    // Say('Image: ' + AItem.FileName);
    result := false;
    AAreas := TCatalogAreas.Create (TCatalogArea, '');

    // are there areas for this image?
    AHasAreas := Catalog.EnumAreasForImage (AItem, AAreas);
    if (AHasAreas) then
    begin
        // go over each area and check if it has an orphan area tag
        for i := 0 to AAreas.Count - 1 do
        begin
            if (not areaHasMatchingLabel(AAreas.Items[i], AItem)) then
            begin
                result := true;
                break;              // orphan area tag found - no need to check other areas
            end;
        end;
        AProps.Free;
    end;
    AAreas.Free;
end;

vlad
Posts: 895
Joined: 01 Sep 08 15:20

Re: Scripts for detecting and fixing orphan area tags

Post by vlad » 10 Feb 16 1:06

Assign Labels for Orphan Area Tags.psc:

Code: Select all

{
  Description: This script assigns labels corresponding to orphan area tags.
               (Orphan area tag = an area caption which does not have a corresponding label assignment)
  Author:      Vlad
  Version:     1.0
}

function areaHasMatchingLabel(AARea: TCatalogArea;
                              AItem: TImageItem)  : Boolean;
begin
    result := false;
    if (AArea.Caption = '') then   // no caption found
        result:= true;
    else
    begin
        AProps := TCatalogItemProps.Create (TCatalogItemProp, '');
        Catalog.EnumPropsForImage (AItem, AProps, false, true);
        for j := 0 to AProps.Count-1 do
        begin
            if (AProps.Items[j].PropName = AArea.Caption) then  // matching label found - no need to check other labels
            begin
                result := true;
                break;
            end;
        end;
        AProps.Free;
    end;
end;


var
  ASelectedImage:   TImageItem;
  ACat:             TCatalogPropCategory;

  lastProcessedImage:  TImageItem;
  processedImages:  integer;
  createdLabels:    integer;
  assignedLabels:   integer;
begin
    if Selected.Count = 0 then
    begin
        Say ('No selection made.');
        exit;
    end;

    if not Ask ('Are you sure you want to automatically assign labels for all orphan area tags?') then
        exit;

    Progress.Cancel := False;
    Progress.ProgressBar := True;
    Progress.Max := Selected.Count;
    Progress.Show;

    lastProcessedImage := nil;
    processedImages := 0;
    createdLabels  := 0;
    assignedLabels := 0;

    for count := 0 to Selected.Count - 1 do
    begin
        ASelectedImage := Selected.Items[count];
        Progress.ProgressText := ASelectedImage.FileName;
        Progress.Pos := count + 1;
        if Progress.Cancel then
            break;

        AAreas := TCatalogAreas.Create (TCatalogArea, '');

        // are there areas for this image?
        AHasAreas := Catalog.EnumAreasForImage (ASelectedImage, AAreas);
        if (not AHasAreas) then
        begin
            AAreas.Free;
            continue;       // process the next image
        end;

        // go over each area and check if it has an orphan area tag
        for i := 0 to AAreas.Count - 1 do
        begin
            AArea := AAreas.Items[i];
            if (areaHasMatchingLabel(AArea, ASelectedImage)) then  // continue with checking the next area tag
                continue;

            AProp := TCatalogItemProp.Create(nil);
            if (not Catalog.FindPropByName(AArea.Caption, AProp, '', true)) then
            begin
                //Say('Label not found for area tag:' + AArea.Caption);

                // create a new label with the area tag as its name
                AProp.GUID := NewGUID; // generate a new GUID
                AProp.PropName := AArea.Caption;

                // place it (by convention) into the designated category ('People')
                ACat := TCatalogPropCategory.Create(nil);
                if (not Catalog.EnumCategoryNamed('People', ACat)) then
                begin
                    // create the category
                    ACat.CategoryName := 'People';
                    Catalog.UpdateCategory(ACat);
                end;
                Catalog.StorePropToDatabase (AProp, ACat.GUID, false);
                createdLabels := createdLabels + 1;
                //Catalog.AddPropToItem (ACat, AProp, false, false);
                ACat.Free;
            end;
            Catalog.AddPropToImage(ASelectedImage, AProp, false, false);   // assign the label to the image
            assignedLabels := assignedLabels + 1;
            if (lastProcessedImage <> ASelectedImage) then
            begin
                lastProcessedImage := ASelectedImage;
                processedImages := processedImages + 1;
            end;
            AProp.Free;
        end;
        AAreas.Free;
    end;
    if (assignedLabels = 0) then
        Say('Done. No orphan area tags were found in selected images.');
    else
        if (createdLabels = 0) then
            Say('Done. Assigned ' + inttostr(assignedLabels) + ' labels to ' +
                inttostr(processedImages) + ' images.');
        else
            Say('Done. Assigned ' + inttostr(assignedLabels) + ' labels (' +
                inttostr(createdLabels) + ' new) to ' + inttostr(processedImages) + ' images.');
end;


Mke
Posts: 505
Joined: 15 Jun 14 15:39

Re: Scripts for detecting and fixing orphan area tags

Post by Mke » 16 Feb 16 16:09

Hi Vlad

Thanks for your work.

I've run Assign Labels for Orphan Area Tags and it found and fixed a few problems - very helpful.
I tried running the Filter With Orphan Area Tags first, though, and it didn't give any indication of doing anything; did something maybe get left out in your cut-and paste?

fbungarz
Posts: 1559
Joined: 08 Dec 06 5:03
Location: Arizona, USA

Re: Scripts for detecting and fixing orphan area tags

Post by fbungarz » 16 Feb 16 18:56

Hi Vlad,
why do you not submit your scripts to the repository? They are so much harder to find on the forum!
Frank

vlad
Posts: 895
Joined: 01 Sep 08 15:20

Re: Scripts for detecting and fixing orphan area tags

Post by vlad » 18 Feb 16 13:20

Mke wrote: I tried running the Filter With Orphan Area Tags first, though, and it didn't give any indication of doing anything; did something maybe get left out in your cut-and paste?
Hi Mke, could you please download the script from the original attachment and let me know if it works for you?

Mke
Posts: 505
Joined: 15 Jun 14 15:39

Re: Scripts for detecting and fixing orphan area tags

Post by Mke » 22 Feb 16 2:08

Hi Vlad

Gave that a try, but there's still no indication of anything happening.

Post Reply