Differentiate between RGB and RGB Grayscale

Anyone, especially newbies, asking for help with Photoshop Scripting and Photoshop Automation - as opposed to those contributing to discussion about an aspect of Photoshop Scripting

Moderators: Tom, Kukurykus

lordtiesto
Posts: 1
Joined: Sat Oct 16, 2021 12:32 am

Differentiate between RGB and RGB Grayscale

Post by lordtiesto »

Hello! I'm working with scanned pictures. Some of them are in color and some are old grayscale pictures. The scanner saved both as RGB.

I would like to know if there's any way to differentiate them in Photoshop to create an script
I tried using the mean of each color channel (thinking that when the picture is grayscale they would have all the same mean) but they're still slightly different

Just to complete the idea: ¿why do I need to differentiate them? Because I want to apply a preset if the picture is in color, and another preset when the pictures is in grayscale

Thank you!
User avatar
Kukurykus
Posts: 528
Joined: Mon Jul 25, 2016 12:36 pm

Re: Differentiate between RGB and RGB Grayscale

Post by Kukurykus »

Maybe to help in understanding the problem post some screenshots to show how it looks now and what you want to achieve.
User avatar
Stephen_A_Marsh
Posts: 29
Joined: Sun Aug 04, 2019 12:37 pm

Re: Differentiate between RGB and RGB Grayscale

Post by Stephen_A_Marsh »

The colour RGB images would have very different channel content: R, G, B.

The greyscale RGB images would (should) have the same channel content: R = G = B.

Comparing the histogram content for each channel would be one possible solution, however it sounds like this is not a perfectly desaturated image.

Can you provide links to a handful of the images? There should be a more significant difference in the std. dev. value between full colour and "near" grey. Is there a common difference such as the std. dev. always being higher than the mean in the colour images? There must be some pattern that can be used to identify, which can then be used by a script to add metadata or run an action or specific processing etc.

Perhaps the eyes will win in this task – so use Adobe Bridge to sort/rank/label and then automation can be performed based on such metadata.
User avatar
Stephen_A_Marsh
Posts: 29
Joined: Sun Aug 04, 2019 12:37 pm

Re: Differentiate between RGB and RGB Grayscale

Post by Stephen_A_Marsh »

Perhaps this may help somebody:

https://community.adobe.com/t5/bridge-d ... p/14141472

Code: Select all

/*
Batch Log Non-Neutral B&W Files from Input Folder.jsx
https://community.adobe.com/t5/bridge-discussions/script-to-find-colour-in-quot-black-amp-white-quot-jpgs/td-p/14141472
v1.1 - 11th October 2023, Stephen Marsh

Info:
This Photoshop script will process the root/top-level of an input folder
for supported files and will log files to the desktop in a text file
that have a Standard Deviation value for the sum of the a+b channels
that is greater than 0.00 (0.00 being fully neutral). A new folder
named "Rejected" will be created in the input folder and documents
which fail will be moved to this folder.
*/

#target photoshop

if (app.documents.length === 0) {

    // Select the folder containing the files
    var inputFolder = Folder.selectDialog("Select the input folder", "");

    // Add or remove supported file extensions as required
    var inputFiles = inputFolder.getFiles(/\.(jpg|jpeg|tif|tiff|psd|psb|png|bmp|webp|tga)$/i);
    inputFiles.sort();

    // Set the input file counter
    var inputFileCounter = 0;

    // Set the failed file counter
    var failedCounter = 0;

    // Initial log file entries
    var dateTime = new Date().toLocaleString();
    var logFile = new File("~/Desktop/Neutral File Evaluation.log");
    if (logFile.exists)
        logFile.remove();
    var os = $.os.toLowerCase().indexOf("mac") >= 0 ? "mac" : "windows";
    if (os === "mac") {
        var logFileLF = "Unix";
    } else {
        logFileLF = "Windows";
    }
    logFile.open("w");
    logFile.encoding = "UTF-8";
    logFile.lineFeed = logFileLF;
    logFile.writeln(dateTime);
    logFile.writeln(inputFolder.fsName + "/" + "Rejects" + "/");
    logFile.close();

    // Process the files
    for (var i = 0; i < inputFiles.length; i++) {
        open(inputFiles[i]);
        
        // Convert to Lab mode
        activeDocument.changeMode(ChangeMode.LAB);
        
        // Histogram evaluation
        var aCha = theHistProps(activeDocument.channels[1].histogram);
        var bCha = theHistProps(activeDocument.channels[2].histogram);
        // theMean = [0] | theMedian = [1] | theStandDev = [2]
        var theValue = (((aCha[2] + bCha[2]) / 2).toFixed(2));
        
        /* Change neutral target value as required */
        if (theValue > 0.00) {

            // Rejected files variables and folder
            var theDoc = activeDocument;
            var theName = theDoc.name;
            var theFolder = Folder(theDoc.path + "/" + "Rejects");
            if (!theFolder.exists) {
                theFolder.create()
            }

            try {
                writeFailedLogEntry();
                failedCounter++;
                
                // Copy the rejected files
                File(theDoc.fullName).copy(theFolder + "/" + theName);
                
                // Remove the original files
                theDoc.fullName.remove();

            } catch (e) {}
            // Close without saving
            activeDocument.close(SaveOptions.DONOTSAVECHANGES);
        } else {
            // Close without saving
            activeDocument.close(SaveOptions.DONOTSAVECHANGES);
        }
        inputFileCounter++;
    }

    // End of script notification
    alert(inputFileCounter + " files processed:" + "\r" + failedCounter + " files failed");

} else {
    alert('No documents should be open when running this script!');
}


///// FUNCTIONS /////

function writeFailedLogEntry() {
    var os = $.os.toLowerCase().indexOf("mac") >= 0 ? "mac" : "windows";
    if (os === "mac") {
        var logFileLF = "Unix";
    } else {
        logFileLF = "Windows";
    }
    logFile.open("a");
    logFile.encoding = "UTF-8";
    logFile.lineFeed = logFileLF;
    logFile.writeln("FAILED = (" + theValue + ") " + activeDocument.name + "\r");
    logFile.close();
}

function theHistProps(theHist) {
    /* Based on https://community.adobe.com/t5/photoshop/how-to-get-the-histogram-s-std-dev/td-p/9875041 */
    // get total number;
    var thePixels = 0;
    for (var m = 0; m < theHist.length; m++) {
        thePixels = thePixels + theHist[m];
    }
    // get mean and median
    var theMean = 0;
    var aTotal = 0;
    var check = false;
    for (var n = 0; n < theHist.length; n++) {
        theMean = theMean + (n * theHist[n] / thePixels);
        aTotal = aTotal + theHist[n];
        if (aTotal >= thePixels / 2 && check === false) {
            theMedian = n;
            check = true;
        }
    }
    // get standard deviation
    var theStandDev = 0;
    for (var o = 0; o < theHist.length; o++) {
        theStandDev = theStandDev + (Math.pow((o - theMean), 2) * theHist[o]);
    }
    theStandDev = Math.sqrt(theStandDev / thePixels);
    // Return the properties: theMean = [0] | theMedian = [1] | theStandDev = [2]
    return ([theMean, theMedian, theStandDev]);
}