question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

safeSearchDetection not finding image

See original GitHub issue

I’ve been stuck on this problem for the past 36 hours. I’m going through the Codelabs tutorial for Firebase Cloud Functions

My app is already deployed to firebase hosting, I’m using version 0.14.0 of nodejs-vsion. However, when doing the image moderation part and after deploying, first I got this error

TypeError: Vision is not a constructor

referring to my require and constructor statements

const Vision = require('@google-cloud/vision');
const vision = new Vision();

Which are copied exactly from the tutorial.

I saw in the documentation, that I should use

const vision = require('@google-cloud/vision');
const client = new vision.ImageAnnotatorClient();

So I changed my code to

const Vision = require('@google-cloud/vision');
const vision = new Vision.ImageAnnotatorClient();

It deploys but now when I upload an image, it displays on the app but it doesn’t get blurred as it’s supposed to. Instead, I get an error in the function logs saying

Error: No image present. at _coerceRequest (/user_code/node_modules/@google-cloud/vision/src/helpers.js:68:21) at ImageAnnotatorClient.<anonymous> (/user_code/node_modules/@google-cloud/vision/src/helpers.js:223:12) at ImageAnnotatorClient.wrapper [as annotateImage] (/user_code/node_modules/@google-cloud/vision/node_modules/@google-cloud/common/src/util.js:746:29) at ImageAnnotatorClient.<anonymous> (/user_code/node_modules/@google-cloud/vision/src/helpers.js:140:17) at /user_code/node_modules/@google-cloud/vision/node_modules/@google-cloud/common/src/util.js:777:22 at ImageAnnotatorClient.wrapper [as safeSearchDetection] (/user_code/node_modules/@google-cloud/vision/node_modules/@google-cloud/common/src/util.js:761:12) at exports.blurOffensiveImages.functions.storage.object.onChange.event (/user_code/index.js:75:17) at correctMediaLink (/user_code/node_modules/firebase-functions/lib/providers/storage.js:78:20) at /user_code/node_modules/firebase-functions/lib/cloud-functions.js:35:20 at process._tickDomainCallback (internal/process/next_tick.js:135:7)

Here is the relevant code straight from the tutorial,

const image = {
    source: {imageUri: `gs://${object.bucket}/${object.name}`}
};

return vision.safeSearchDetection(image)
    .then(batchAnnotateImagesResponse => {

So I switched to the code that is in the docs, instead of using the ‘image’ object, I just put the image url directly inside the safeSearchDetection function

return vision.safeSearchDetection(`gs://${object.bucket}/${object.bucket}`)

(The back-ticks around the argument won’t display correctly because they are how markdown displays code format) (edited by @stephenplusplus)

And now the error in the Function logs is

blurOffensiveImages 
  [ 
    { 
        faceAnnotations: [],
        landmarkAnnotations: [],
        logoAnnotations: [],
        labelAnnotations: [],
        textAnnotations: [],
        safeSearchAnnotation: null,     
        imagePropertiesAnnotation: null,    
        error:   {   
                details: [],        
                code: 7,        
                message: 'Error opening file: gs://friendlychat-XXXX.appspot.com/XXXXXXX/-XXXXXXXXX/XXXXXXX.jpg.' },
        cropHintsAnnotation: null,     
        fullTextAnnotation: null,     
        webDetection: null 
   } 
]

My object.bucket is the ‘friendlychat-XXXX.appspot.com’ part and my object.name is the ‘XXXXXXX/-XXXXXXXXX/XXXXXXX.jpg’ part

I don’t know what else to do. I’ve tried reverting back to version 0.12.0 and 0.11.0 and nothing helps. Those just give me different errors requiring me to change the vision = new Vision... constructor. And even after making adjustments, the image still isn’t able to be found.

Again, the image uploads, but the function to blur isn’t running because it can’t find the image. I’m really stuck here.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:1
  • Comments:19 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
00hellocommented, Jan 29, 2018

@shekharskamble You’re welcome.

“Storage Object Creator” & “Storage Object Viewer” permissions

With regards to “Storage Object Creator” & “Storage Object Viewer” permissions, after following the link I posted above (now below) –

https://console.cloud.google.com/iam-admin/iam/project?project= friendlychat-XXXXX (replace “friendlychat-XXXXX” with whatever your project’s id is)

– I trust, you’ll see something that looks like this.

screenshot

There should be an “App Engine default service account” listed (second from the top in the screenshot). Click the little dropdown button to the right. See where mine says “multiple” (Yours probably won’t say “multiple” because it might only have one permission selected). Scroll down the list till you get to “Storage” near the bottom. Drag your mouse over the blue arrow to the right of “Storage” and the “Storage …” permission menu should make itself visible as you can see in the screenshot.

Code

And here’s the code. The parts that I commented out still remain to show you what wasn’t needed. Also, I kept the console logs that I was using to debug. Let me know if this works for you.

exports.blurOffensiveImages = functions.storage.object().onChange(event => {
    const object = event.data;
    //const file = gcs.bucket(object.bucket).file(object.name);
    
    // Exit if this is a deletion or a deploy event.
    if (object.resourceState === 'not_exists') {
    return console.log('This is a deletion event.');
    } else if (!object.name) {
    return console.log('This is a deploy event.');
    }

    // const image = {
    //    source: {imageUri: `gs://${object.bucket}/${object.name}`}
    // };
    
    // var visionPromise = file.download()
    //     .then(resp => {
    //         var imageContents = resp[0];
    //         return vision.safeSearchDetection(`gs://${object.bucket}/${object.name}`);
    //     })
  
  
    // Check the image content using the Cloud Vision API.
    return vision.safeSearchDetection(`gs://${object.bucket}/${object.name}`).then(batchAnnotateImagesResponse => {
            console.log("batchAnnotateImagesResponse");
            console.log(batchAnnotateImagesResponse);
            console.log("batchAnnotateImagesResponse[0]");
            console.log(batchAnnotateImagesResponse[0]);
            const safeSearchResult = batchAnnotateImagesResponse[0].safeSearchAnnotation;
            console.log("safeSearchResult.adult");
            console.log(safeSearchResult.adult);
            //const Likelihood = Vision.types.Likelihood;
            if (Likelihood[safeSearchResult.adult] >= Likelihood.LIKELY ||
                Likelihood[safeSearchResult.violence] >= Likelihood.LIKELY) {
                console.log('The image', object.name, 'has been detected as inappropriate.');
                return blurImage(object.name, object.bucket);
            } else {
                console.log('The image', object.name,'has been detected as OK.');
            }
        })
        .catch(err => {
            console.log('Search Detecion failed.', err);
        });
});

1reaction
stephenpluspluscommented, Dec 21, 2017

First of all, thanks for putting up with the version changes and the out of date docs. I’ll work separately to see who owns them and correct the examples so nobody else has to endure what you have.

It seems to me like you’ve found the correct way to use our code. The error that you ended up with:

‘Error opening file: gs://friendlychat-XXXX.appspot.com/XXXXXXX/-XXXXXXXXX/XXXXXXX.jpg.’

That is directly from the API, un-touched by our client library. So, for some reason, the API cannot find your image by specifying it as a gs:// path. I would try downloading the image locally and pushing it right up in the request:

const bucket = gcs.bucket(object.bucket);
const file = bucket.file(object.name);

file.download()
  .then(resp => {
    var imageContents = resp[0];
    return vision.safeSearchDetection(imageContents);
  })
  .catch(err => {
    console.log('Image downloading failed.', err):
  });

Hope that works 🤞 Sorry again for all of the inconsistencies and changes.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Detect explicit content (SafeSearch) | Cloud Vision API
SafeSearch Detection detects explicit content such as adult content or violent content within an image. This feature uses five categories ( adult ,...
Read more >
Implement the Safe Search Detection feature of the Vision API ...
The Safe Search detection feature is implemented in such a way that it puts constraints on the image fields. If the user enables...
Read more >
Google Vision API - Running Explicit Content Detection (Safe ...
ImageAnnotatorClient() image = vision. ... Testing using command !python detect.py --safe-search-uri ... enter image description here.
Read more >
Google Vision API in Python (Part 13): Detect Explicit Content ...
In this tutorial we are going to learn how to use Google Vision API Safe Search Detection feature to filter inappropriate contents.
Read more >
Detect explicit content (Safe Search) - Price 2 Meet
https://cloud.google.com/vision/docs/detecting-safe-search. 2/6. Explicit content detection on a local image. Create or select a project.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found