You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何让基于jsQR的浏览器二维码扫描器仅识别二维码,避免误识别

Fixing False Positives (Misidentifying Non-QR Code Objects) in jsQR

I’ve worked with jsQR extensively, and that false positive issue is super common when dealing with textured surfaces like keyboards or rugs—here are concrete, actionable fixes to get your scanner to only recognize actual QR codes:

1. Tune jsQR’s Detection Parameters

By default, jsQR tries to detect both light-on-dark and dark-on-light QR codes, which can lead to misinterpreting complex textures as QR patterns. Restricting this behavior cuts down on false hits:

// Modify your jsQR call to include these options
var code = jsQR(imageData.data, imageData.width, imageData.height, {
  inversionAttempts: "dontInvert", // Only look for standard dark-on-light QR codes (most common)
  // Use "both" if you need to support inverted codes, but pair it with the checks below
});

2. Add Confidence Threshold Filtering

Every code object returned by jsQR has a confidence value (0 to 1) indicating how sure it is about the detection. False positives almost always have low confidence—filter them out:

if (code) {
  // Reject low-confidence results (adjust the threshold based on your testing)
  if (code.confidence < 0.9) {
    outputMessage.hidden = false;
    requestAnimationFrame(tick);
    return;
  }
  
  // ... rest of your logic
}

3. Validate the Detected Data Format

False positives usually spit out garbled text (like random Chinese characters) that doesn’t match real QR code content. Add checks for your expected data format:

  • If scanning URLs: Use a regex like /^https?:\/\/.+/
  • If using custom business codes: Check for a specific prefix (e.g., code.data.startsWith("MY_APP_"))
  • For general cases: Filter out non-printable ASCII characters (most valid QR codes use these):
if (code) {
  // ... run confidence check first
  
  const printableAsciiRegex = /^[\x20-\x7E]+$/;
  if (!printableAsciiRegex.test(code.data)) {
    outputMessage.hidden = false;
    requestAnimationFrame(tick);
    return;
  }
  
  // ... your existing drawing and processing logic
}

Bonus: Fix the Syntax Error in Your Code

I spotted a typo that might cause issues: the stray dataQR) right before alert(code.data);—remove that closing parenthesis to avoid runtime errors.

Updated Detection Block (Putting It All Together)

Here’s how your revised tick function’s detection logic should look:

function tick() {
  loadingMessage.innerText = "Loading video..."
  if (video.readyState === video.HAVE_ENOUGH_DATA) {
    loadingMessage.hidden = true;
    canvasElement.hidden = false;
    outputContainer.hidden = false;
    canvasElement.height = video.videoHeight;
    canvasElement.width = video.videoWidth;
    canvas.drawImage(video, 0, 0, canvasElement.width, canvasElement.height);
    var imageData = canvas.getImageData(0, 0, canvasElement.width, canvasElement.height);
    
    // Updated jsQR call with detection options
    var code = jsQR(imageData.data, imageData.width, imageData.height, {
      inversionAttempts: "dontInvert"
    });
    
    if (code) {
      // Filter low-confidence results
      if (code.confidence < 0.9) {
        outputMessage.hidden = false;
        requestAnimationFrame(tick);
        return;
      }
      
      // Filter non-printable/garbled data
      const printableAsciiRegex = /^[\x20-\x7E]+$/;
      if (!printableAsciiRegex.test(code.data)) {
        outputMessage.hidden = false;
        requestAnimationFrame(tick);
        return;
      }
      
      // Your existing drawing logic
      drawLine(code.location.topLeftCorner, code.location.topRightCorner, "#FF3B58");
      drawLine(code.location.topRightCorner, code.location.bottomRightCorner, "#FF3B58");
      drawLine(code.location.bottomRightCorner, code.location.bottomLeftCorner, "#FF3B58");
      drawLine(code.location.bottomLeftCorner, code.location.topLeftCorner, "#FF3B58");
      outputMessage.hidden = true;
      
      if(code.data.trim() !== ""){
        var dataQR = "qrData=" + code.data;
        document.cookie = dataQR;
        frmAction('serviceid',true,false);
        alert(code.data);
        vidOff();
      } else {
        var dataQR = "qrData=";
        document.cookie = dataQR;
        document.cookie = "toastMsg=Yes";
        frmAction('serviceid',true,false);
        vidOff();
      }
    } else {
      outputMessage.hidden = false;
    }
  }
  requestAnimationFrame(tick);
  
  function vidOff() {
    video.pause();
    video.src = "";
    video.srcObject.getVideoTracks().forEach(track => track.stop());
    console.log("camera off");
  }
}

Test these changes with the problematic surfaces (keyboard, rug)—you should see false positives disappear while valid QR codes are still detected correctly.

内容的提问来源于stack exchange,提问作者Kundan SIngh

火山引擎 最新活动