• javascript+canvas身份证背景颜色识别


    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>身份证背景颜色识别title>
        <style>
            #img{
                width: 200px;
                height: 240px;
            }
        style>
    head>
    <body>
        <input id="fileBtn" name="file" type="file" accept="image/*">	
        <img src="" alt="" id="img">
        <div id="res">div>
    body>
    <script>
        let fileBtn = document.querySelector("#fileBtn");
        let images = document.querySelector("#img");
        let res = document.querySelector("#res");
        
        const cvs = document.createElement('canvas');
        const ctx = cvs.getContext("2d", {
            willReadFrequently: true
        });
        cvs.style.cssText="margin-top: 20px;";
        document.body.appendChild(cvs);
    
    
        // 监听文件上传
        fileBtn.addEventListener('change', function(e){
            const file = e.target.files[0];
            const reader = new FileReader();
            reader.onload = function(event) {
                const img = new Image();
                img.src = event.target.result;
                images.src = event.target.result;
                 
                img.onload = function() {
                    // 将图像绘制到Canvas上
                    cvs.width = img.width;
                    cvs.height = img.height;
                    ctx.drawImage(img, 0, 0);
                    
                    // 获取图片左上角和右上角的颜色
                    const colorData = ctx.getImageData(0, 0, cvs.width, cvs.height); // 获取Canvas中的颜色信息
                    // const colors = getSurroundingColors(colorData, cvs.width, cvs.height);
                    // console.log(colors);
                    // if(isSurroundingWhite(colors)){
                    //     console.log('ok')
                    // }else{
                    //     console.log('no')
                    // }
    
                    const mainColor = getMainColor(colorData);
                    console.log('主色系', mainColor);
    
                    // 获取Canvas中左上角像素的颜色信息
                    const pixelData = ctx.getImageData(0, 0, 1, 1).data;
    
                    // 判断左上角像素的颜色是否接近白色(可根据需求调整阈值)
                    const isWhite = isColorWhite(pixelData);
                    if (isWhite) {
                        console.log("背景色是白色");
                    }else if(isBlueColor(mainColor)){
                        console.log('背景是蓝色');
                    }else if(isRedColor(mainColor)){
                        console.log('背景是红色');
                    }else{
                        console.log('未检测出背景色');
                    }
                    
    
                };
            };
    
            reader.readAsDataURL(file);
        })
        // 检测背景是否为白色(通过rgb判断)
        function isColorWhite(pixelData) {
            // 判断颜色是否接近白色,可根据实际需求调整阈值
            const redThreshold = 220;
            const greenThreshold = 220;
            const blueThreshold = 220;
            const [red, green, blue] = pixelData;
            return red >= redThreshold && green >= greenThreshold && blue >= blueThreshold;
        }
        // 将rgb转为hsv
        function rgbToHsv(r, g, b){
            // 将RGB值转换为0到1的范围
            r /= 255;
            g /= 255;
            b /= 255;
    
            const max = Math.max(r, g, b);
            const min = Math.min(r, g, b);
            const delta = max - min;
            let h, s, v;
            if (delta === 0) {
                h = 0;
            } else if (max === r) {
                h = (60 * ((g - b) / delta) + 360) % 360;
            } else if (max === g) {
                h = (60 * ((b - r) / delta) + 120) % 360;
            } else {
                h = (60 * ((r - g) / delta) + 240) % 360;
            }
    
            s = max === 0 ? 0 : delta / max;
            v = max;
            return [h,s,v];
        }
        // 检测背景是否为蓝色(通过rgb转hsv的方式判断)
        function isBlueColor(pixelData) {
            const [red, green, blue] = pixelData;
            const [h, s, v] = rgbToHsv(red, green, blue);
    
            // 定义蓝色的HSV范围
            const lowerHue = 200;  // 蓝色在HSV中的色相范围
            const upperHue = 230;
            const lowerSaturation = 0.3;  // 蓝色的饱和度范围
            const upperValue = 0.9;  // 蓝色的明度范围
            console.log(h, s, v);
    
            // 检查颜色是否在蓝色范围内
            if (h >= lowerHue && h <= upperHue && s >= lowerSaturation && v >= upperValue) {
                return true;
            } else {
                return false;
            }
        }
        // 检测背景是否为红色
        function isRedColor(pixelData){
            const [red, green, blue] = pixelData;
            const [h, s, v] = rgbToHsv(red, green, blue);
            // 定义红色的HSV范围
            const lowerHue = 0;  // 红色在HSV中的色相范围
            const upperHue = 15;
            const lowerSaturation = 0.3;  // 红色的饱和度范围
            const upperValue = 0.9;  // 红色的明度范围
    
            // 检查颜色是否在红色范围内
            if (h >= lowerHue && h <= upperHue && s >= lowerSaturation && v >= upperValue) {
                return true;
            } else {
                return false;
            }
        }
        
        /**
         * 获取左上角和右上角周围颜色
         * @param {array} pixelData 图像中所有颜色值
         * @param {string} width 画布的宽度
         * @param {string} height 画布的高度
         * @param {int} rangeValue 范围值
        */
        function getSurroundingColors(pixelData, width, height, rangeValue=20){
            let topLeftColors = [];
            let topRightColors = [];
            for(let y=0; y<height; y++){
                for(let x=0; x<width; x++){
                    // 计算当前像素位置
                    const index = (y * width + x) * 4;
                    // 左上角
                    if(y <= rangeValue && x <= rangeValue){
                        // pixelData.data.set([0, 255, 0, 255], index);
                        topLeftColors.push([
                            // index,
                            pixelData.data[index],
                            pixelData.data[index+1],
                            pixelData.data[index+2],
                            pixelData.data[index+3]
                        ]);
                    }
                    // 右上角
                    if(y <= rangeValue && x >= width-rangeValue){
                        // pixelData.data.set([0, 255, 0, 255], index);
                        topRightColors.push([
                            // index,
                            pixelData.data[index],
                            pixelData.data[index+1],
                            pixelData.data[index+2],
                            pixelData.data[index+3]
                        ]);
                    }
    
                }
            }
            let res = {
                topLeftColors,
                topRightColors
            };
            return res;
        }
        // 验证左上角和右上角指定像素是否为白色
        function isSurroundingWhite(colors){
            const redThreshold = 220;
            const greenThreshold = 220;
            const blueThreshold = 220;
            const topLeftColors = colors.topLeftColors;
            const topRightColors = colors.topRightColors;
            let left_res = false;
            for(var l=0; l<topLeftColors.length; l++){
                const left_r = topLeftColors[l][0];
                const left_g = topLeftColors[l][1];
                const left_b = topLeftColors[l][2];
                const left_a = topLeftColors[l][3];
                left_res = left_r >= redThreshold && left_g >= greenThreshold && left_b >= blueThreshold;
                // console.log(left_res);
            }
    
            let right_res = false;
            for(let r=0; r<topRightColors.length; r ++){
                const right_r = topLeftColors[r][0];
                const right_g = topLeftColors[r][1];
                const right_b = topLeftColors[r][2];
                const right_a = topLeftColors[r][3];
                right_res = right_r >= redThreshold && right_g >= greenThreshold && right_b >= blueThreshold;
            }
            // console.log(left_res, right_res);
            if(left_res && right_res){
                return true;
            }else{
                return false;
            }
        }
        // 获取主色系
        function getMainColor(pixelData){
            // 创建一个对象来存储颜色出现次数
            const data = pixelData.data;
            const colorCounts = {};
    
            // 遍历像素数据
            for (let i = 0; i < data.length; i += 4) {
                const red = data[i];
                const green = data[i + 1];
                const blue = data[i + 2];
                const color = `rgb(${red},${green},${blue})`;
                // 统计颜色出现次数
                if (colorCounts[color]) {
                    colorCounts[color]++;
                } else {
                    colorCounts[color] = 1;
                }
            }
            // console.log(colorCounts);
    
            // 找到出现次数最多的颜色
            let maxColor = '';
            let maxCount = 0;
            for (const color in colorCounts) {
                if (colorCounts[color] > maxCount) {
                    maxCount = colorCounts[color];
                    maxColor = color;
                }
            }
    
            let subColor = maxColor.substring(maxColor.indexOf('(')+1, maxColor.length-1);
            let colorArr = subColor.split(',');
            return colorArr;
        }
        
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
  • 相关阅读:
    java完整面试复习
    NoSQL redis 过期key处理
    【java基础系列】16- Java中怎么处理异常?
    IBM Spectrum LSF 重要的目录和配置文件
    【解决方案】危化品厂区安防系统EasyCVR+AI智能监控
    Java 9 的模块(Module)系统
    ssh登录时间久或登陆后报错
    spring boot入门与理解MVC三层架构
    Linux系统编程(信号处理机制)
    开路、断路和短路区别
  • 原文地址:https://blog.csdn.net/admin_web/article/details/133792330