需求:
給出一串尺寸相同的商品鞋圖片,將它們鞋頭的朝向判斷出來,例如:
思路:
其實找到規律非常簡單,
- 我們首先得統一一下尺寸 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 我都會盡力幫大家哦
本文的文字及圖片來源于網路加上自己的想法,僅供學習、交流使用,不具有任何商業用途,著作權歸原作者所有,如有問題請及時聯系我們以作處理
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/67747.html
標籤:JavaScript
