zoukankan      html  css  js  c++  java
  • 如何用nodejs实现图片分析看商品朝向呢?本文教你

    需求:

    给出一串尺寸相同的商品鞋图片,将它们鞋头的朝向判断出来。例如:

    先展示一下最后的效果:

    思路:

    其实找到规律非常简单。

    • 我们首先得统一一下尺寸 1000 宽度,不然的话之后像素位置判断很难统一,这里可以使用批量的图片工具转一下就行(不要问为什么8张图也要转,我们模拟的是上千张图)。
    • 接下来,我们需要开始找规律,再说之前,先来一张图:我们先分为两大区域,A区和B区,撇去logo不看,鞋子都有一个规律:右边低,左边高。我们就从这个地方切入。

    nodejs分析图片像素:

    初始化一个项目,然后安装下我们的依赖:npm i get-pixels --save。这个包用于读取图的像素信息。 我们先展示下初始代码:

    var getPixels = require("get-pixels");
    var fs = require("fs");
    var path = require("path");
    getPixels(img, function (err, pixels) {
          if (err) {
            return false
          }else{
            console.log(pixels)  
          }我是08年出道的高级前端老鸟,有问题或者交流经验可以进我的扣扣裙 519293536 我都会尽力帮大家哦
    })

    我们拿到了像素信息,我这里用了一张50-50像素的图片作为演示,图片太大不利于我们分析。发现它跑出来了这么多像素信息:

    shap里面是我们的图片宽高等信息,data里面是像素的详细信息,但是它分的不够明确,50-50的图片,拆分出来了10000个像素信息,我们需要转化成像素,4个一个rgba,变成50-50的像素点,类似于这样的结构: [[rgb],[rgb],[rgb],[rgb]] 于是这块是我们接下来要去做的:

    var arr = []; //对像素进行收集,三个一组rgb
    var arrtemp = []; //临时的数组,用于储存拿到的临时三个rgb
    pixels.data.forEach((item, index) => {
            if (index % 4 === 0) {
              arr.push(arrtemp)
              arrtemp = [] //对像素储存空间重置
            } else {
              arrtemp.push(item)
            }
          });
    复制代码

    最后我们得到的 arr 就是我们需要的啦!这里变量的命名,我展示的比较随意,根据大家自己业务需求去命名,好的命名可维护性很重要哦。

    接下来我们还需要去判断,第一个像素出现的位置。通过ps来吸一下颜色看看。

    • 底色的颜色
    • 物体的颜色
    很明显,rgb数值越小,越可能出现我们需要的物体,那么这里就可以来做一个判断了。我这里设置的阈值是低于200,我就认为是物体,你们也可以根据自己需要来,我的代码只是大概粗略的,大家可以根据自己能力去优化:
          var width = pixels.shape[0]; //收集图片宽度
          var arr = []; //对像素进行收集,三个一组rgb
          var arrtemp = []; //临时的数组,用于储存拿到的临时三个rgb
          var flag = true; //是否需要判断第一个目标像素点位置
          var okIndex = 0; //目标像素出现的位置
          var indexindex = 0; //记录循环中目标像素点的计数累加
          pixels.data.forEach((item, index) => {
            if (index % 4 === 0) {
              arr.push(arrtemp)
              indexindex++;
              if (flag) {
                if ((((arrtemp.filter((item2) => item2 < 200)).length) > 1)) { //像素值如果大于200 就是目标像素
                  okIndex = indexindex
                  flag = !flag
                }
              }
              arrtemp = [] //对像素储存空间重置
            } else {
              arrtemp.push(item)
            }
          });
          arr.shift()
          console.log('最高像素出现在:', (okIndex / width).toFixed(2).toString().split('.')[1], '%位置上')
    复制代码

    做到这里之后,差不多鞋子的判断也都出来了

     if ((okIndex / width).toFixed(2).toString().split('.')[1] < 50) { //只要超过画布一半 就认为是
            console.log('鞋头朝右')
            res('鞋头朝右')
          } else {
            console.log('鞋头朝左')
            res('鞋头朝左')
          }
    复制代码

    但是这样会有一个问题,可以看到有些图片是带有左上角logo的,这种怎么解决呢? 也简单,我们设置一下行数,一张图片多少行像素之前,我们就先不判断它,到了后面几行,才开始判断。

    const noCheckLine = 160; //需要忽略的行,例如顶上有Adidas logo打标干扰判断像素位置
    if ((((arrtemp.filter((item2) => item2 < 200)).length) > 1) && indexindex / width > noCheckLine) //像素值如果大于200 就是目标像素
    复制代码

    根据这样的判断,我们就可以从指定的行数才开始去找自己要的那个像素点了。

    至此,我们如果需要批量的话,可以发现,这个东西其实是回调函数,不太好批量操作,我们封装成promise,加上async函数,完美~

    var getPixels = require("get-pixels");
    var fs = require("fs");
    var path = require("path");
    
    (async () => {
      ......
    })()
    
    function getInformation(img) {
      return new Promise((res, rej) => {
        getPixels(img, function (err, pixels) {
          if (err) {
            rej('图片拉取失败!')
          }
          ......
          if ((okIndex / width).toFixed(2).toString().split('.')[1] < 50) { //只要超过画布一半 就认为是
            res('鞋头朝右')
          } else {
            res('鞋头朝左')
          }
        })
      })
    }
    
    复制代码

    再展示一下最后的效果:

    留下的问题:

    拖鞋,凉鞋以及侧面的该怎么去判断呢?这里的方法并不适用于这些,但是并不代表着没有办法。

    拖鞋类,我们可以反过来判断,那么怎么判断是不是拖鞋呢?像素信息密度就可以,指定一个阈值。 凉鞋类也可以根据具体的产品样本去找出规律。
    • 问:这种准确率又达不到百分百,那还是不靠谱呀!
    • 答:问题一般能解决掉95%,剩下来的5%就是调整参数了。如果需要更好的解决方案,可以尝试人工智能,但我想,那么大批量的素材需要训练出来,也许等训练完,肉眼都看完了....并且模型的训练,也要考虑到众多的样本特征。记住我:我是08年出道的高级前端老鸟,有问题或者交流经验可以进我的扣扣裙 519293536 我都会尽力帮大家哦

      本文的文字及图片来源于网络加上自己的想法,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理

  • 相关阅读:
    【BZOJ3105】【CQOI2013】新Nim游戏
    【BZOJ3884】上帝与集合的正确用法
    【BZOJ3518】点组计数
    【BZOJ4804】欧拉心算
    【BZOJ4059】Non-boring sequences
    【BZOJ 4016】 [FJOI2014]最短路径树问题
    【BZOJ 2744】【HEOI2012】朋友圈
    【BZOJ4417】: [Shoi2013]超级跳马
    【BZOJ 2713】[Violet 2]愚蠢的副官&&【BZOJ1183】[Croatian2008]Umnozak——【数位DP】
    【BZOJ】1969: [Ahoi2005]LANE 航线规划
  • 原文地址:https://www.cnblogs.com/chengxuyuanaa/p/13097989.html
Copyright © 2011-2022 走看看