Logo detection sounds like one of those tasks that should be easy.
You upload an image, ask the computer, “Hey, is there a Nike logo here?”, and it answers yes or no.
Then reality walks in.
The logo may be tiny. It may be rotated. It may be on a shirt, a billboard, a coffee cup, a blurry event photo, a YouTube thumbnail, or a product package. Sometimes you need to detect any brand logo. Sometimes you need to detect one specific logo. Sometimes you need a bounding box around the logo. Sometimes you only need a label like:
{
“brand”: “Google”,
“confidence”: 0.94
}
So before writing JavaScript, we need to pick the right logo detection approach.
In this guide, we’ll go through practical ways to detect logos in images with JavaScript:
- Use Google Cloud Vision for ready-made logo detection.
- Use Amazon Rekognition for brand/object label detection.
- Use Roboflow if you need a custom logo detector.
- Use TensorFlow.js when you want browser or Node.js model inference.
- Use OpenCV.js template matching for simple fixed-logo checks.
- Add a safe production workflow with confidence thresholds and review.
Why we can write this guide
We’ve spent around 6 years working with AI APIs, computer vision workflows, image processing, automation, and developer tutorials. We also researched current logo detection docs, JavaScript-friendly computer vision tools, and logo recognition research for this article.
The practical lesson is simple: logo detection is not one single problem.
Detecting a famous brand logo in a clean image is one thing. Detecting your company’s logo on real-world event photos is another. Detecting a small, distorted, partially hidden logo on a moving video frame is another level of pain entirely.
That is why this guide gives you several routes instead of pretending one code snippet solves every logo problem.
First, what kind of logo detection do you need?
Start here, because this choice decides everything.
| You need to… | Best starting option |
| Detect common/famous logos | Google Cloud Vision logo detection |
| Detect brands or objects in marketing images | Amazon Rekognition labels |
| Detect one specific logo in predictable images | OpenCV.js template matching |
| Detect custom logos in real-world images | Roboflow custom object detection |
| Run detection in the browser | TensorFlow.js or Roboflow inference.js |
| Build a production brand monitoring tool | Custom model + review workflow |
| Extract logo location with a bounding box | Object detection model |
| Just know if a known logo appears | Cloud Vision/API route may be enough |
If you only need “does this image contain a recognizable brand logo?”, use a cloud API first.
If you need “where exactly is my logo in this image?”, use an object detection model.
If you need “does this exact logo appear in a fixed layout?”, template matching may be enough.
What should the output look like?
A useful logo detection result should include more than a brand name.
For example:
{
“found”: true,
“logo”: “Google”,
“confidence”: 0.96,
“bounding_box”: {
“x”: 120,
“y”: 80,
“width”: 240,
“height”: 90
},
“source”: “google_vision”
}
For production apps, these fields help a lot:
| Field | Why it matters |
| found | Easy yes/no result |
| logo or brand | Which logo was detected |
| confidence | Helps avoid false positives |
| bounding_box | Lets you draw a box or crop the logo |
| source | Tracks which model/API returned the result |
| image_id | Links result back to your database |
| review_required | Sends uncertain images to humans |
| error | Helps debug failed requests |
Without confidence and review logic, logo detection can get messy fast.
Option 1: Use Google Cloud Vision logo detection
Google Cloud Vision is one of the easiest ways to detect famous logos.
Google’s docs say the Vision API can detect and extract information about multiple logos in an image, and the logo detection samples show LOGO_DETECTION as the feature type for detecting logos in local or Cloud Storage images. That fits this tutorial because we want a ready API that already knows many common brands.
This option is great when you do not want to train a custom model.
When Google Cloud Vision makes sense
Use it when:
| Need | Fit |
| Famous brand logo detection | Strong |
| Quick API integration | Strong |
| No model training | Strong |
| Detect logo names | Strong |
| Custom private logo detection | Weaker |
| Browser-only detection | Use backend proxy |
| Exact logo location/control | Depends on response details and use case |
You should call Google Vision from your backend, not directly from frontend JavaScript. API keys and service credentials should stay server-side.
Node.js example with Google Cloud Vision
Install:
npm install @google-cloud/vision
Create detect-logo-google.js:
import vision from “@google-cloud/vision”;
const client = new vision.ImageAnnotatorClient();
async function detectLogo(imagePath) {
const [result] = await client.logoDetection(imagePath);
const logos = result.logoAnnotations || [];
return logos.map((logo) => ({
description: logo.description,
score: logo.score,
boundingPoly: logo.boundingPoly
}));
}
const logos = await detectLogo(“./image.jpg”);
console.log(JSON.stringify(logos, null, 2));
Example output:
[
{
“description”: “Google”,
“score”: 0.94,
“boundingPoly”: {
“vertices”: [
{ “x”: 120, “y”: 80 },
{ “x”: 360, “y”: 80 },
{ “x”: 360, “y”: 170 },
{ “x”: 120, “y”: 170 }
]
}
}
]
Now your app can show the detected brand and draw a box around it.
API route example for your app
In a real app, create a backend endpoint.
import express from “express”;
import vision from “@google-cloud/vision”;
const app = express();
const client = new vision.ImageAnnotatorClient();
app.use(express.json({ limit: “10mb” }));
app.post(“/detect-logo”, async (req, res) => {
try {
const { imagePath } = req.body;
if (!imagePath) {
return res.status(400).json({
error: “imagePath is required”
});
}
const [result] = await client.logoDetection(imagePath);
const logos = result.logoAnnotations || [];
return res.json({
found: logos.length > 0,
logos: logos.map((logo) => ({
name: logo.description,
confidence: logo.score,
bounding_box: logo.boundingPoly
})),
source: “google_cloud_vision”
});
} catch (error) {
return res.status(500).json({
error: “Logo detection failed”,
details: error.message
});
}
});
app.listen(3000, () => {
console.log(“Logo detection API running on port 3000”);
});
This backend route is much safer than putting cloud credentials in the browser.
Option 2: Use Amazon Rekognition for brand and object signals
Amazon Rekognition does not work exactly the same way as Google Vision logo detection, but it can still help with brand/image analysis workflows.
Amazon Rekognition’s DetectLabels API detects real-world entities in images and returns labels, confidence scores, instances, parents, aliases, categories, and the model version used. The docs also explain that MinConfidence controls the minimum confidence required for labels to be returned.
That matters because many brand workflows are not only about logos. You may also want to detect objects, products, scenes, signs, packaging, or visual context.
When Amazon Rekognition makes sense
Use it when:
| Need | Fit |
| AWS-native image analysis | Strong |
| General object/label detection | Strong |
| Confidence thresholds | Strong |
| S3 image workflows | Strong |
| Custom logo detection | Use Rekognition Custom Labels or another custom model |
| Dedicated logo detection | Google Vision may be simpler |
| Browser-only workflow | Use backend proxy |
If your images already live in S3, Rekognition is especially convenient.
Node.js example with Amazon Rekognition
Install:
npm install @aws-sdk/client-rekognition
Example:
import {
RekognitionClient,
DetectLabelsCommand
} from “@aws-sdk/client-rekognition”;
const client = new RekognitionClient({
region: “us-east-1”
});
async function detectLabelsFromS3(bucket, name) {
const command = new DetectLabelsCommand({
Image: {
S3Object: {
Bucket: bucket,
Name: name
}
},
MaxLabels: 20,
MinConfidence: 80
});
const response = await client.send(command);
return response.Labels.map((label) => ({
name: label.Name,
confidence: label.Confidence,
categories: label.Categories,
instances: label.Instances
}));
}
const labels = await detectLabelsFromS3(
“your-bucket-name”,
“images/sample.jpg”
);
console.log(JSON.stringify(labels, null, 2));
This may return labels like Logo, Trademark, Text, Poster, Bottle, Clothing, or brand-related visual categories depending on the image and model behavior.
For exact logo detection, you may need a custom model.
Option 3: Use Roboflow for custom logo detection
If you need to detect your own logo, a client logo, or a niche brand logo, a custom object detection model is usually the better path.
This means you train a model with labeled examples:
Image → logo bounding box → logo class
Roboflow is useful because it helps with dataset management, annotation, training, deployment, and JavaScript-friendly inference.
Roboflow’s docs show hosted object detection inference options, including JavaScript examples for the Hosted API. Roboflow also has browser deployment docs for inference.js, which is a JavaScript package for real-time inference in the browser using models trained on Roboflow.
That fits custom logo detection because your app may need either hosted API inference or browser-based inference.
When Roboflow makes sense
Use it when:
| Need | Fit |
| Custom logo detection | Strong |
| Bounding boxes | Strong |
| Dataset annotation | Strong |
| Hosted API | Strong |
| Browser inference | Supported through inference.js |
| No training/data work | Use Google Vision first |
| Detect all famous logos automatically | Use a ready logo API first |
Custom logo detection needs data. You cannot expect a model to detect a private logo it has never seen.
What data do you need?
Start with at least a small dataset.
| Dataset item | Recommendation |
| Positive examples | Images containing the logo |
| Negative examples | Similar images without the logo |
| Variations | Different sizes, angles, lighting, backgrounds |
| Real context | Shirts, packages, posters, screens, photos |
| Labels | Bounding boxes around each logo |
| Test set | Images the model never saw during training |
A logo recognition paper called Scalable Logo Recognition using Proxies explains why this problem is tricky: logos have many variations, brands change over time, and retraining for every logo variation can become impractical. The paper frames logo recognition as a few-shot object detection problem and uses a universal logo detector plus a recognizer. This supports the point here: for custom or large-scale logo detection, you need a model and dataset strategy, not only a quick keyword-like API call.
Hosted API example with JavaScript
A hosted API call usually looks like this pattern:
async function detectCustomLogo(imageUrl) {
const modelEndpoint = “your-model/your-version”;
const apiKey = process.env.ROBOFLOW_API_KEY;
const response = await fetch(
`https://detect.roboflow.com/${modelEndpoint}?api_key=${apiKey}&image=${encodeURIComponent(imageUrl)}`,
{
method: “POST”
}
);
if (!response.ok) {
throw new Error(`Roboflow request failed: ${response.status}`);
}
const result = await response.json();
return result.predictions.map((prediction) => ({
class: prediction.class,
confidence: prediction.confidence,
x: prediction.x,
y: prediction.y,
width: prediction.width,
height: prediction.height
}));
}
Keep the API key on the server if this is part of a real app.
Option 4: Run logo detection in the browser with TensorFlow.js
Browser-based logo detection is useful when you want lower latency, privacy, or offline-ish behavior.
TensorFlow.js lets developers run machine learning models in the browser or Node.js. The TensorFlow.js paper, TensorFlow.js: Machine Learning for the Web and Beyond, explains that TF.js supports running ML models in web browsers and Node.js and enables on-device computation. That fits logo detection because some apps do not want every image sent to a server.
You can use TensorFlow.js in two main ways:
- Load a custom object detection model exported to TF.js format.
- Use a JavaScript inference wrapper from a platform like Roboflow.
When browser detection makes sense
Use it when:
| Need | Fit |
| Low-latency detection | Strong |
| Images should stay on device | Strong |
| Real-time camera detection | Strong |
| Offline or edge workflow | Possible |
| Big custom model | May be heavy |
| Easy setup | Hosted API is easier |
| Strong server-side scaling | Use backend inference |
Browser inference is powerful, but model size matters. A large model can slow down page load and burn user device resources.
Basic TensorFlow.js model loading shape
Install:
npm install @tensorflow/tfjs
Example structure:
import * as tf from “@tensorflow/tfjs”;
async function loadLogoModel() {
const model = await tf.loadGraphModel(“/models/logo-detector/model.json”);
return model;
}
async function runLogoDetection(model, imageElement) {
const input = tf.browser
.fromPixels(imageElement)
.resizeBilinear([640, 640])
.toFloat()
.div(255.0)
.expandDims(0);
const predictions = await model.executeAsync(input);
input.dispose();
return predictions;
}
The exact post-processing depends on your model. YOLO-style models, SSD models, and custom exported models all return different output shapes.
So the honest advice is: if you use a custom model, keep the model’s export docs nearby.
Option 5: Use OpenCV.js template matching for one known logo
Template matching is the simplest old-school option.
You have:
- A target image.
- A logo template image.
- OpenCV searches for the region that best matches the template.
OpenCV’s JavaScript template matching tutorial explains that template matching slides a template image over the input image and compares the template with each image patch.
This can work well when:
| Situation | Template matching fit |
| Logo size is similar | Good |
| Logo angle is similar | Good |
| Image layout is predictable | Good |
| Logo is exact and clean | Good |
| Logo is rotated, distorted, tiny, or hidden | Weak |
| Many logos/classes | Weak |
| Real-world photos | Usually weak |
So template matching is not the best general logo detector. But for controlled images, it can be enough.
OpenCV.js example idea
Your HTML might have:
<img id=”sourceImage” src=”image.jpg” />
<img id=”logoTemplate” src=”logo.png” />
<canvas id=”canvasOutput”></canvas>
JavaScript shape:
function detectLogoWithTemplate() {
const src = cv.imread(“sourceImage”);
const templ = cv.imread(“logoTemplate”);
const dst = new cv.Mat();
const mask = new cv.Mat();
cv.matchTemplate(src, templ, dst, cv.TM_CCOEFF_NORMED, mask);
const result = cv.minMaxLoc(dst, mask);
const maxPoint = result.maxLoc;
const confidence = result.maxVal;
const color = new cv.Scalar(255, 0, 0, 255);
const point1 = maxPoint;
const point2 = new cv.Point(
maxPoint.x + templ.cols,
maxPoint.y + templ.rows
);
cv.rectangle(src, point1, point2, color, 2, cv.LINE_8, 0);
cv.imshow(“canvasOutput”, src);
src.delete();
templ.delete();
dst.delete();
mask.delete();
return {
confidence,
x: maxPoint.x,
y: maxPoint.y,
width: templ.cols,
height: templ.rows,
found: confidence > 0.8
};
}
This is a nice lightweight trick for controlled layouts.
For example:
- Checking if a watermark appears in a generated image.
- Finding a logo in a fixed document layout.
- Detecting a known icon in a screenshot.
- Checking if a brand mark appears in a template.
For real-world brand monitoring, use object detection instead.
How do you draw bounding boxes on the image?
Once you have detection results, drawing boxes is simple.
Example with canvas:
<canvas id=”imageCanvas”></canvas>
function drawDetections(image, detections) {
const canvas = document.getElementById(“imageCanvas”);
const context = canvas.getContext(“2d”);
canvas.width = image.width;
canvas.height = image.height;
context.drawImage(image, 0, 0);
context.lineWidth = 3;
context.font = “16px Arial”;
detections.forEach((detection) => {
const { x, y, width, height, label, confidence } = detection;
context.strokeRect(x, y, width, height);
context.fillText(
`${label} ${Math.round(confidence * 100)}%`,
x,
Math.max(y – 8, 16)
);
});
}
For Google Vision, you may need to convert polygon vertices to a rectangular box.
function boundingPolyToBox(boundingPoly) {
const vertices = boundingPoly.vertices || [];
const xs = vertices.map((point) => point.x || 0);
const ys = vertices.map((point) => point.y || 0);
const minX = Math.min(…xs);
const minY = Math.min(…ys);
const maxX = Math.max(…xs);
const maxY = Math.max(…ys);
return {
x: minX,
y: minY,
width: maxX – minX,
height: maxY – minY
};
}
Now you can display results in a browser UI.
What should a production workflow look like?
For a real app, build the flow like this:
- User uploads image.
- App stores image or sends it to backend.
- Backend runs logo detection.
- Backend normalizes output into one JSON format.
- App checks confidence threshold.
- High-confidence detections pass automatically.
- Medium-confidence detections go to review.
- Low-confidence results are ignored or marked as “not found.”
- App stores the result with image ID and model/API source.
- Human reviewers correct false positives and false negatives.
That review loop matters because logo detection can fail.
A logo can be tiny, blurry, stylized, partially covered, or similar to another logo. The model may also detect a brand from packaging or text nearby instead of the actual logo.
What confidence threshold should you use?
Start with a strict threshold.
| Confidence | Suggested action |
| 0.90+ | Auto-accept for low-risk workflows |
| 0.70-0.89 | Send to review |
| Below 0.70 | Mark uncertain or ignore |
This depends on the app.
For brand monitoring, you may want high recall, so you review more uncertain matches.
For compliance or takedown workflows, you want fewer false positives, so use stricter thresholds and human review.
How do you evaluate logo detection?
Please test with real images.
Use:
- Clean product images.
- Blurry photos.
- Social media screenshots.
- Event photos.
- Images with multiple logos.
- Images with similar-looking logos.
- Rotated logos.
- Partial logos.
- Tiny logos.
- Negative examples with no logo.
Track:
| Metric | What it tells you |
| Precision | How many detected logos were correct |
| Recall | How many real logos were found |
| False positives | Wrong logo detections |
| False negatives | Missed logos |
| Bounding box quality | Whether the box actually covers the logo |
| Confidence calibration | Whether scores match real quality |
| Latency | Whether detection is fast enough |
| Review rate | How much human checking remains |
Research supports this kind of real-world testing. Roboflow 100, a multi-domain object detection benchmark, argues that object detection models are often evaluated on fixed datasets that may not represent many real-life domains. That fits logo detection because a model that works on clean product images may struggle with social screenshots, sports footage, event photos, or blurry user uploads.
Where LLMAPI fits
LLMAPI can fit after logo detection when your app needs AI workflow steps around the result.
Logo detection gives you structured visual evidence:
{
“logo”: “Nike”,
“confidence”: 0.92,
“box”: {
“x”: 120,
“y”: 80,
“width”: 200,
“height”: 90
}
}
LLMAPI can help with follow-up tasks:
| Task | Example |
| Brand monitoring summary | “Summarize where this brand appears across images.” |
| Moderation notes | “Explain why this image needs review.” |
| Report generation | “Create a weekly brand visibility report.” |
| Metadata enrichment | “Add tags and campaign labels.” |
| Customer-facing messages | “Draft a notice asking user to replace copyrighted logo.” |
| Workflow routing | “Send high-risk cases to legal, low-risk cases to marketing.” |
| Multi-model fallback | Use different models for summarization, review, or routing |
A useful workflow can be:
- JavaScript uploads the image.
- Cloud Vision, Rekognition, Roboflow, or a TF.js model detects logos.
- Your backend stores normalized logo results.
- LLMAPI helps summarize, classify, route, or report the results.
- A human reviews uncertain cases.
That keeps computer vision and language reasoning in their own lanes.
Common mistakes
Logo detection is easy to demo and easy to overtrust.
Watch out for these:
| Mistake | Better approach |
| Calling cloud APIs directly from frontend | Use a backend proxy |
| Expecting generic APIs to know private logos | Train a custom detector |
| Ignoring confidence | Add thresholds and review |
| No negative examples | Test images without the logo |
| Using template matching for real-world photos | Use object detection |
| No bounding boxes | Store location when possible |
| Testing only clean images | Test real messy uploads |
| No human review | Review medium-confidence matches |
| Mixing different API outputs | Normalize results into one format |
| No model/API source tracking | Store which detector produced the result |
The biggest mistake is choosing the tool before defining the problem.
The build-ready version
If you want a simple first version, build this:
- Backend endpoint: /detect-logo.
- Google Cloud Vision logo detection for common logos.
- Normalized JSON response.
- Confidence threshold.
- Canvas UI to draw bounding boxes.
- Store results in your database.
- Add manual review for uncertain detections.
If you need your own logo, build this instead:
- Collect real images with and without the logo.
- Label bounding boxes.
- Train a custom detector in Roboflow or another CV platform.
- Deploy through hosted API or browser inference.
- Add confidence thresholds and review.
- Keep collecting corrections to improve the model.
If the image layout is predictable and the logo is always the same size, try OpenCV.js template matching first. It is simple, cheap, and surprisingly useful for controlled cases.
The practical takeaway
Logo detection in JavaScript can mean a few different things.
For common brands, use Google Cloud Vision’s logo detection API. For AWS-based image workflows, test Amazon Rekognition. For your own logo or a client’s private brand mark, train a custom object detection model with Roboflow or another vision platform. For browser-side detection, use TensorFlow.js or Roboflow inference.js. For simple fixed-logo checks, use OpenCV.js template matching.
The best setup depends on the image type, logo type, accuracy needs, and deployment style.
A good first production workflow is simple: detect the logo, return confidence and bounding box, draw the result, store the output, and send uncertain cases to review. That gives you useful automation without pretending computer vision is perfect.