blog icon indicating copy to clipboard operation
blog copied to clipboard

使用 ADB 和 Node.js 训练抖音模型——寻找好看的小姐姐

Open huruji opened this issue 4 years ago • 1 comments

自己刷抖音时训练的模型不行呀,推荐给我的都是一些沙雕视频,都是抠脚大汉,很少漂亮的小姐姐,但是自己刷抖音训练的话又太耗时间了,刚看看了 ADB ,发现这个简直就是宝库,想着就要不就使用 ADB 来帮我训练一下,省的我手动训练了。

关于 ADB,可以看我之前的文章,ADB 实用笔记

首先使用 Node.js 封装下 ADB 的命令,为了兼容连接多台设备的问题,可以使用一个标志位,同时每次使用的时候使用 use 方法来指定对应的设备,call 方法作为所有调用命令的基础方法:

const { exec } = require('child_process')
const path = require('path')

let currentDeviceName = ''
let isVerbose = false

const call = (code) => {
  return new Promise((resolve, reject) => {
    const command = `adb ${currentDeviceName ? `-s ${currentDeviceName}` : ''} ${code}`

    if (isVerbose) console.log(command, '\n')

    exec(command, (err, stdout, stderr) => {
      if (err) reject(new Error(err + ''))
      resolve(stdout)
    })
  })
}

const use = (device) => currentDeviceName = device.name
const verbose = (value) => isVerbose = value

添加对应的设备查询方法,并通过解析字符串的形式来将设备保存为数组:

const rawDevices = () => call('devices')

const devices = async () => {
  return (await rawDevices())
    .split(/\n/)
    .map(line => line.split('\t'))
    .filter(line => line.length > 1)
    .map(device => ({ name: device[0].trim(), status: device[1].trim() }))
}

现在完成了 ADB 查询设备的基本操作。那么问题就是怎么识别抖音的视频里有好看的小姐姐呢?

我想的就是通过人脸识别的 API 来判断,可以通过 ADB 来截图,然后调用相应的 AI 接口判断截图中人的颜值和性别,然后再决定是否关注和点赞该视频,然后上滑切换到下一个视频,如此反复。

整理一下,需要封装的 ADB 命令就是点击命令、滑动和截图命令:

const touch = (x, y) => call(`shell input tap ${x} ${y}`)

const swipe = (x1, y1, x2, y2, ms = 200) => call(`shell input swipe ${x1} ${y1} ${x2} ${y2} ${ms} `)

const screenshot = (filename = 's.png', localSavePath = './') => call(`shell screencap -p > ${path.resolve(localSavePath, filename)}`)

接着就是看看市场上的 AI 接口了,我选择的是 Face++ 的接口,https://www.faceplusplus.com.cn/face-detection/:

在注册完成后可以在控制台的应用管理看到对应的试用的 API key 和 API Secret

和大多数开放平台一样,是通过将这两个值传递给后台来鉴权的,并且试用类型是免费的。

在控制台的人脸识别栏目下的 Detect API 下可以看到对应的请求接口参数要求和相应的返回,https://console.faceplusplus.com.cn/documents/4888373

在可选参数 return_attributes 里的 genderbeauty 就是判断性别和颜值的。

接口返回值格式如下:

其中 faces 是一个数组,其实也很容易理解,毕竟一张图片里可能不止一个人吗,每张脸的的颜值 beauty 是一个对象,区分了在男女眼中的颜值。真相了,男生和女生的审美不一样!

基于上面的分析可以开始写代码了,通过 https 模块调用接口即可,为了方便将图片通过 base64 的形式传递,大致如下:

const https = require('https');
const querystring = require('querystring');
const { base64Sync } = require('base64-img')


module.exports = function (file, scoreLevel = 70) {
  const base64 = base64Sync(file)
  const data = querystring.stringify({
    api_key: "自己的api_key",
    api_secret: "自己的api_secret",
    image_base64: base64,
    return_attributes: 'gender,age,beauty'
  })

  const options = {
    host: 'api-cn.faceplusplus.com',
    path: '/facepp/v3/detect',
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
    }
  }

  return new Promise((resolve, reject) => {
    const req = https.request(options, (res) => {
      res.on('data', (d) => {
        let b = {}
        try {
          b = JSON.parse('' + d)
        } catch (err) {
          resolve({
            shouldFollow: false
          })
          return
        }

        const faces = b.faces || []

        let shouldFollow = false
        let score = 0

        for (let i = 0; i < faces.length; i++) {
          const attrs = faces[i].attributes
          score = attrs.beauty.male_score
          if (attrs.gender.value == 'Female' && attrs.beauty.male_score >= scoreLevel) {
            shouldFollow = true
            break
          }
        }
        resolve({
          shouldFollow,
          score
        })
      })

    });
    req.on('error', (e) => {
      resolve(false)
    });
    req.write(data)
    req.end()
  })
}

这里对外接受文件和颜值分数要求,如果返回的 faces 数组中有大于这个分数要求并且性别是小姐姐的话就关注和点赞。

为了更好地训练效果,可以在点赞和关注的视频里多停留一会儿,这样抖音就更加知道我们喜欢看小姐姐了。

接着就是处理对应的点赞和关注的 tap 操作,这个我是通过我自己手机屏幕的分辨率和按钮位置大致估算出来的(更精确的可以截一张抖音的图然后通过 faststone 之类的工具量出位置):

我试的是点赞 1300 是可以的,关注 1200 是可以的,我的手机分辨率是 1080 X 2280

上滑操作其实很好处理,x轴不变,y轴变小即可。

以上分析完后,先实现个等待函数。

function awaitMoment(time = 2000) {
  return new Promise((resolve) => {
    setTimeout(() => resolve(), time)
  })
}

设备打开抖音后,先上滑切换一个视频

async function main() {
  const device = (await adb.devices())[0]

  adb.use(device)
  adb.verbose(true)

  await adb.swipe(200, 1000, 200, 100, 200)

  await awaitMoment()
}

等待两秒后截一个图,(这里做的很粗糙,因为两秒的截图可能没有小姐姐,但是实践证明,这样训练是可以的),然后调用 face++ 的接口,根据结果来是否关注和点赞,然后删掉对应的截图,接着调用这个方法:


const fileName = ((Math.random() + '').substr(2, 7)) + '.png'
  await adb.screenshot(fileName, path.resolve(__dirname, 'images'))
  const file = path.resolve(path.resolve(__dirname, 'images', fileName))

  const { shouldFollow, score } = await face(file, 70)

  console.log('shouldFollow', shouldFollow)
  console.log('score', score)

  if (shouldFollow) {

    await adb.touch(1000, 1300)
    await adb.touch(1000, 1200)

    await awaitMoment(5000)
  }

  fs.unlinkSync(file)

  await main()

这样基本就大功告成了。

运行即可啦,接着就是等待程序自动帮助我们关注好看的小姐姐了。

我大概训练了2,3个小时,效果还是很明显的,抖音从给我推荐各种沙雕视频变成了各种小姐姐,抖音推荐算法牛逼呀,哈哈哈哈,这样上班划水的时候也欢乐。

因为 gif 图太大,太麻烦了,所以就简单拍了个视频,可以看看程序训练的过程,爱奇艺链接 http://www.iqiyi.com/w_19saaayji1.html、油管链接 https://www.youtube.com/watch?v=-_Gwd3DHJZU&feature=youtu.be

最后看下我的账号经过训练的效果:

(其实也有一个问题,就是滤镜太严重了,很多网红脸,不知道有没有识别网红脸的算法)

以上所有的代码都开源在了我的 github 上,地址是 https://github.com/huruji/find-beauty-in-douyin

我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2gawvno0mn8kk

huruji avatar Jul 13 '19 17:07 huruji

赞👍

onblog avatar Jan 19 '20 05:01 onblog