• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Selecting the main subject (Biggest)

Engaged ,
Dec 31, 2018 Dec 31, 2018

Copy link to clipboard

Copied

Hello everyone,

I attached some picture of what I want to do, I already put a threshold adjustment layer, now i want to select the biggest black object in the picture.

It is a one piece, and usually in different places so recording magic wand for example in the same location every time won't help, also Photoshop "Select Subject" isn't a good solution.

here are the pictures, let me know what you think

TOPICS
Actions and scripting

Views

1.7K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

LEGEND , Jan 03, 2019 Jan 03, 2019

The value you switched to is too low as process will take too long time. Use at least value 2 or higher like I suggested so it's going to work very fast. I was aware of edges they will be rounded, and adviced to add part of code that fix that (however I guess you could do it manually).

You must specify the value of Magic Wand if you use 'Select / Grow'. I'm not sure why you then use Expand +4, but if you added additional step that selecting black pixels again you had perfect selection of your car

...

Votes

Translate

Translate
Adobe
LEGEND ,
Dec 31, 2018 Dec 31, 2018

Copy link to clipboard

Copied

You may change .5 to bigger value so the process will be faster but less precious, and error may occur on too small paths:

sTT = stringIDToTypeID, dsc = new ActionDescriptor()

dsc.putEnumerated(sTT('colors'), sTT('colors'), sTT('shadows'))

dsc.putInteger(sTT('shadowsUpperLimit'), 0), dsc.putBoolean(sTT('invert'), false)

ref1 = new ActionReference(), ref2 = new ActionReference(), ref1.putClass(sTT('path'))

dsc.putReference(sTT('null'), ref1), ref2.putProperty(sTT('selectionClass'), sTT('selection'))

dsc.putReference(sTT('from'), ref2), dsc.putUnitDouble(sTT('tolerance'), sTT('pixelsUnit'), .5)

executeAction(sTT('colorRange'), dsc), executeAction(sTT('make'), dsc)

len = (sPI = (pI0 = (aD = activeDocument).pathItems[0]).subPathItems).length

for(arr = [], i = 0; i < len; i++) {

     for(pts = [], j = 0; j < (pP = sPI.pathPoints).length;) pts.push(pP[j++].anchor);

     (sel = aD.selection).select(pts), hst = aD.histogram[0]

     if (!arr.length || hst > arr[0][0]) arr[0] = [hst, pts]

}

pI0.remove(), sel.select(arr[0][1])

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Dec 31, 2018 Dec 31, 2018

Copy link to clipboard

Copied

tried that with .5 and it took like 10 minutes and returned an error, is there a way to do it without paths? (i think it takes too long)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 31, 2018 Dec 31, 2018

Copy link to clipboard

Copied

Didn't you try with higher value like 10? If you're getting still error link me to uploaded image you're having it with.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jan 01, 2019 Jan 01, 2019

Copy link to clipboard

Copied

these are the 3 layers I have, which one should I choose before the script?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 01, 2019 Jan 01, 2019

Copy link to clipboard

Copied

I created above layers. Bottom with White fill, middle with gray fill of objects & transparency, top with thereshold set to 255.

With all visible layers I activated the middle one, then I ran script and it worked (with 10 value) - selected the biggest object.

If you can't get expected result then like I said - upload one or more documents you're having error with so I'll see it myself.

By the error I meant Photoshop crashes what I found why happens. If you want above code worked change first 7 lines to:

sTT = stringIDToTypeID, dsc = new ActionDescriptor()

dsc.putEnumerated(c = sTT('colors'), c, sTT('shadows'))

executeAction(sTT('colorRange'), dsc)

dsc.putInteger(sTT('shadowsUpperLimit'), 0), dsc.putBoolean(sTT('invert'), false)

ref1 = new ActionReference(), ref2 = new ActionReference(), ref1.putClass(sTT('path'))

dsc.putReference(sTT('null'), ref1), ref2.putProperty(sTT('selectionClass'), sTT('selection'))

dsc.putReference(sTT('from'), ref2), dsc.putUnitDouble(sTT('tolerance'), sTT('pixelsUnit'), 1)

executeAction(sTT('make'), dsc)

You may also change 1 (prev. 0.5) value to higher one, or better add to script 'Select / Grow' so it'll select all found black px.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jan 02, 2019 Jan 02, 2019

Copy link to clipboard

Copied

the first script:

sTT = stringIDToTypeID, dsc = new ActionDescriptor() 

dsc.putEnumerated(sTT('colors'), sTT('colors'), sTT('shadows')) 

dsc.putInteger(sTT('shadowsUpperLimit'), 0), dsc.putBoolean(sTT('invert'), false

ref1 = new ActionReference(), ref2 = new ActionReference(), ref1.putClass(sTT('path')) 

dsc.putReference(sTT('null'), ref1), ref2.putProperty(sTT('selectionClass'), sTT('selection')) 

dsc.putReference(sTT('from'), ref2), dsc.putUnitDouble(sTT('tolerance'), sTT('pixelsUnit'), .5

executeAction(sTT('colorRange'), dsc), executeAction(sTT('make'), dsc) 

len = (sPI = (pI0 = (aD = activeDocument).pathItems[0]).subPathItems).length 

for(arr = [], i = 0; i < len; i++) { 

for(pts = [], j = 0; j < (pP = sPI.pathPoints).length;) pts.push(pP[j++].anchor); 

    (sel = aD.selection).select(pts), hst = aD.histogram[0] 

if (!arr.length || hst > arr[0][0]) arr[0] = [hst, pts] 

pI0.remove(), sel.select(arr[0][1])

returned:

^ it also took a lot of time

this script

sTT = stringIDToTypeID, dsc = new ActionDescriptor() 

dsc.putEnumerated(sTT('colors'), sTT('colors'), sTT('shadows')) 

dsc.putInteger(sTT('shadowsUpperLimit'), 0), dsc.putBoolean(sTT('invert'), false) 

ref1 = new ActionReference(), ref2 = new ActionReference(), ref1.putClass(sTT('path')) 

dsc.putReference(sTT('null'), ref1), ref2.putProperty(sTT('selectionClass'), sTT('selection')) 

dsc.putReference(sTT('from'), ref2), dsc.putUnitDouble(sTT('tolerance'), sTT('pixelsUnit'), 1) 

executeAction(sTT('colorRange'), dsc), executeAction(sTT('make'), dsc) 

len = (sPI = (pI0 = (aD = activeDocument).pathItems[0]).subPathItems).length 

for(arr = [], i = 0; i < len; i++) { 

for(pts = [], j = 0; j < (pP = sPI.pathPoints).length;) pts.push(pP[j++].anchor); 

    (sel = aD.selection).select(pts), hst = aD.histogram[0] 

if (!arr.length || hst > arr[0][0]) arr[0] = [hst, pts] 

pI0.remove(), sel.select(arr[0][1])

returned:

this script:

sTT = stringIDToTypeID, dsc = new ActionDescriptor() 

dsc.putEnumerated(c = sTT('colors'), c, sTT('shadows')) 

executeAction(sTT('colorRange'), dsc) 

 

dsc.putInteger(sTT('shadowsUpperLimit'), 0), dsc.putBoolean(sTT('invert'), false

ref1 = new ActionReference(), ref2 = new ActionReference(), ref1.putClass(sTT('path')) 

dsc.putReference(sTT('null'), ref1), ref2.putProperty(sTT('selectionClass'), sTT('selection')) 

dsc.putReference(sTT('from'), ref2), dsc.putUnitDouble(sTT('tolerance'), sTT('pixelsUnit'), 1

executeAction(sTT('make'), dsc) 

returned:

so every one of them still haven't selected the main subject

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 02, 2019 Jan 02, 2019

Copy link to clipboard

Copied

I don't have your files, but created similar ones on my own and everything worked. So it would be helpful you shared some files it doesn't work on that I ask you now for the 3rd time. Or you do not want to help me while you want I helped you

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jan 02, 2019 Jan 02, 2019

Copy link to clipboard

Copied

Your help is much appreciated!

Here is the image. it came from a NEF file type (RAW image) and the dimensions are 6000x4000px

I saved it as a jpg because the PSD/TIF file or the NEF file is too big (let me know if you want me still to upload the big file and send you a link to it)

But still, save this jpg, Magic Wand on the white part to delete it + add a threshold adjustment layer of 253 then we will be in the same position

let me know, thank you!

DSC_1838.jpg

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 02, 2019 Jan 02, 2019

Copy link to clipboard

Copied

If you shared that file in no time probably you wouldn't wait so long for the code. I've found there was a bug in my code, it didn't work well with your graphics that luckily didn't affect images I created independently. So in my last full code beside the change you did last time please change also lines 13th and 14th ie:

     (sel = aD.selection).select(pts), hst = aD.histogram[0]

     if (!arr.length || hst > arr[0][0]) arr[0] = [hst, pts]


to:

(sel = aD.selection).select(pts), $.level = 0; try{

     sel.bounds, hst = aD.histogram[0]

     if (!arr.length || hst > arr[0][0]) arr[0] = [hst, pts]

}

catch(err){}

Also to make script finished its work in 2 seconds (at least on provided image) instead of for ex. like one minute, use Magic Wand with 10 for tolerance (plus Anti-alias and Contigous) while you are clicking on white area. Remember also to use this time a value 2 or higher in the code where originally I suggested 10 and then changed to 1. Hiding panels speeds up as well.

Share more images since for now I can not imagine all circumstances to write proper script it fitted to most possible cases.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jan 03, 2019 Jan 03, 2019

Copy link to clipboard

Copied

I switched the two lines, value is 1, here is the immediate result:

edges are a bit not precise since it relies on work path:

So I used Select > Grow Like you told me on your first reply + Expand 4px,

It's not perfect because it's via paths but it's good enough, i will try on many more pictures and share them

Thank you

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 03, 2019 Jan 03, 2019

Copy link to clipboard

Copied

The value you switched to is too low as process will take too long time. Use at least value 2 or higher like I suggested so it's going to work very fast. I was aware of edges they will be rounded, and adviced to add part of code that fix that (however I guess you could do it manually).

You must specify the value of Magic Wand if you use 'Select / Grow'. I'm not sure why you then use Expand +4, but if you added additional step that selecting black pixels again you had perfect selection of your carpet. Anyway here is complete code for that:

sTT = stringIDToTypeID, dsc = new ActionDescriptor()

function cR() {

     dsc.putEnumerated(c = sTT('colors'), c, sTT('shadows')), executeAction(sTT('colorRange'), dsc)

}

cR(), dsc.putInteger(sTT('shadowsUpperLimit'), 0), dsc.putBoolean(sTT('invert'), false)

ref1 = new ActionReference(), ref2 = new ActionReference(), ref1.putClass(sTT('path'))

dsc.putReference(sTT('null'), ref1), ref2.putProperty(sTT('selectionClass'), sTT('selection'))

dsc.putReference(sTT('from'), ref2), dsc.putUnitDouble(sTT('tolerance'), sTT('pixelsUnit'), 2)

executeAction(sTT('make'), dsc)

len = (sPI = (pI0 = (aD = activeDocument).pathItems[0]).subPathItems).length

for(arr = [], i = 0; i < len; i++) {

     for(pts = [], j = 0; j < (pP = sPI.pathPoints).length;) pts.push(pP[j++].anchor);

     (sel = aD.selection).select(pts), hst = aD.histogram[0]

     $.level = 0; try{

          sel.bounds; if (!arr.length || hst > arr[0][0]) arr[0] = [hst, pts, i]

     }

     catch(err){}

}

pI0.remove(), sel.select(arr[0][1]), sel.grow(255, true), sel.expand(5), cR()

In the last line instead of sel.grow(255, true), sel.expand(5), cR() you can use sel.contract(5), sel.grow(255, true)​ so it's going to select all little white pixels inside of main subject also to avoid selection of little dark pixels outside of carpet.

And yes share more pictures, I wonder how that will work on rest of them

Ah, and the procedure is accordingly to that you provided:

- there still must be 3 layers (Threshold set to 255, middle main layer and Color Fill - white - layer)

- you make active middle layer, use Magic Wand on White area (with tolerance of 10)

- after you remove and deselect selected white area you run script (value 2)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jan 03, 2019 Jan 03, 2019

Copy link to clipboard

Copied

Perfect.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Jan 03, 2019 Jan 03, 2019

Copy link to clipboard

Copied

For your file.

Select white background with a magic wand.

Run the script.

You will get selected carpet.

select_max_selection();

alert("Done!");

function select_max_selection()

    {

    try {

        // selection to workpath

        var d = new ActionDescriptor();

        var r = new ActionReference();

        r.putClass(stringIDToTypeID("path"));

        d.putReference(stringIDToTypeID("null"), r);

        var r1 = new ActionReference();

        r1.putProperty(stringIDToTypeID("selectionClass"), stringIDToTypeID("selection"));

        d.putReference(stringIDToTypeID("from"), r1);

        d.putUnitDouble(stringIDToTypeID("tolerance"), stringIDToTypeID("pixelsUnit"), 0.5);

        executeAction(stringIDToTypeID("make"), d, DialogModes.NO);

        // leave only one subpath with maximum points;

        var d = new ActionDescriptor();

        var r = new ActionReference();

        r.putEnumerated(stringIDToTypeID("path"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

        var pth = executeActionGet(r).getObjectValue(stringIDToTypeID("pathContents"));          

        var lst = pth.getList(stringIDToTypeID("pathComponents"));          

        var list = new ActionList();             

        var len = lst.count;

        var max;

        var max_obj;

        for (var i = 0; i < len; i++)

            {

            var obj = lst.getObjectValue(i);

            var count = obj.getList(stringIDToTypeID("subpathListKey")).getObjectValue(0).getList(stringIDToTypeID("points")).count;

            if (!max || max < count)

                {

                max = count;

                max_obj  = obj;

                }

            }

        max_obj.putEnumerated(stringIDToTypeID("shapeOperation"), stringIDToTypeID("shapeOperation"), stringIDToTypeID("add") );

        list.putObject(stringIDToTypeID("pathComponent"), max_obj);          

        var r = new ActionReference();

        r.putProperty( charIDToTypeID( "Path" ), charIDToTypeID( "WrPt" ) );

        d.putReference( stringIDToTypeID( "null" ), r );

        d.putList(charIDToTypeID("T   "), list);

        executeAction(charIDToTypeID("setd"), d, DialogModes.NO);

        // workpath to selection

        var d = new ActionDescriptor(); 

        var r = new ActionReference(); 

        r.putProperty(stringIDToTypeID("channel"), stringIDToTypeID("selection")); 

        d.putReference(stringIDToTypeID("null"), r); 

        var r1 = new ActionReference(); 

        r1.putProperty(stringIDToTypeID("path"), stringIDToTypeID("workPath")); 

        d.putReference(stringIDToTypeID("to"), r1); 

     

        d.putBoolean(stringIDToTypeID("antiAlias"), true); 

        d.putUnitDouble(stringIDToTypeID("feather"), stringIDToTypeID("pixelsUnit"), 0); 

     

        executeAction(stringIDToTypeID("set"), d, DialogModes.NO); 

        // delete workpath

        var doc = app.activeDocument;

        for (var i = 0; i < doc.pathItems.length; i++)

            {

            if (doc.pathItems.kind == PathKind.WORKPATH)

                {

                doc.pathItems.remove();

                break;

                }

            }

        }

    catch(e) { alert(e); }

    }

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Feb 07, 2019 Feb 07, 2019

Copy link to clipboard

Copied

LATEST

"Select white background with a magic wand."

is there a way to automate it?

in the following picture I've added a relative 300px enlargement in canvas size, so the 300px "frame" is always white (maybe it can help),

maybe automate choosing top left pixel with magic wand? (resolution might change from picture to picture)

UP1: used Color Range, worked like a charm

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines