- INV Image Tool
- Instalando
- Desinstalando
- Server Websocket
- Workflow
- Executando etapas isoladas do workflow (Development Only)
- Dependency Checker
- Try-out
Ferramenta para validações de elementos IHM de um produto.
A aplicação sobe um servidor websocket localhost:8765
que fica aguardando um workflow para ser executado. Quando recebe um workflow do client
, executa as etapas pré-determinadas no .JSON
e retorna os resultados para o client
em tempo real.
Abra o terminal, e na pasta do script, execute:
npm i @libs-scripts-mep/inv-img-tool
Abra o terminal, e na pasta do script, execute:
npm uninstall @libs-scripts-mep/inv-img-tool
import { IITServer, IITClient } from "../node_modules/@libs-scripts-mep/inv-img-tool/IIT.js"
//💡 Recomendado executar a cada teste o seguinte comando para iniciar o servidor, caso já esteja iniciado, o comando será ignorado.
const serverStart = await IITServer.startWebsocket()
if (!serverStart.success) { throw new Error('Failed server start') }
const relativeRefPath = "../my/relative/path/"
const fileName = "pattern.json"
await IITClient.startWorkflow(relativeRefPath, fileName, streamVideoElement, resultVideoElement, debugMode)
💡Para que seja renderizado o stream de video, é necessário passar um elemento HTML para
streamVideoElement
e/ou um elemento HTML pararesultVideoElement
.
Um workflow
é uma sequência de etapas - steps
- de processamento de imagem sobre o frame da camera - haystack
- relacionando à um conjunto específico de imagens de referência - needle image
.
Esse workflow pode ou não configurar parâmetros do firmware da câmera - cap_props
- afim de alcançar uma condição específica de imagem em uma determinada situação.
{
"pattern1.png": {
"timeout": 5, //tempo em segundos que a aplicação tenta validar a imagem. Cada imagem possui seu proprio timeout configurado.
"result": null, //result em null significa que ainda não foi validada. true ou false são resultados da validação finalizada.
"setup": {
"cap_props": { //❔propriedades opcionais do firmware da câmera. ⚠️ OBS: essas propriedades podem variar de acordo com a câmera.
"BRIGHTNESS": {
"cvenum": 10, //valor do enumerador da biblioteca OpenCV para o respectiva propriedade ⚠️ OBS: NÃO ALTERAR ESSES VALORES.
"value": 128.0, //valor absoluto que será configurado
"min": 0, //valor minimo que o parâmetro influenciará no firmware da câmera. ⚠️ OBS: esses valores podem variar de acordo com a câmera
"max": 255 //valor maximo que o parâmetro influenciará no firmware da câmera. ⚠️ OBS: esses valores podem variar de acordo com a câmera
},
"CONTRAST": {
"cvenum": 11,
"value": 32.0,
"min": 0,
"max": 255
},
"SATURATION": {
"cvenum": 12,
"value": 32.0,
"min": 0,
"max": 255
},
"GAIN": {
"cvenum": 14,
"value": 12.0,
"min": 0,
"max": 255
},
"EXPOSURE": {
"cvenum": 15,
"value": -6.0,
"min": 0,
"max": 15,
"negative": true //Essa propriedade exclusivamente necessita ser passada com valor negativo.
},
"SHARPNESS": {
"cvenum": 20,
"value": 24.0,
"min": 0,
"max": 255
},
"ZOOM": {
"cvenum": 27,
"value": 100.0,
"min": 0,
"max": 400
},
"FOCUS": { //💡câmeras que tem autofoco, é recomendado encontrar o foco ideal, e durante a aplicação sempre configurar esse parâmetro.
"cvenum": 28,
"value": 80,
"min": 0,
"max": 255
}
}
},
"steps": {
"stream": {}, //❔ passo opcional, caso esteja listado nesse objeto, será transmitido para o client os frames da câmera
"homography": { // Realiza correção de PERSPECTIVA, ROTAÇÃO e ESCALA da imagem haystack em relação ao needle
"debug": false //Esse modo habilita janelas durante essa etapa e imagem especificamente para detectar problemas ou ajustar alguma configuração.
},
"template": { //⚠️ OBS: `main_color`, `template` e `template_xor` são as únicas etapas que realizam validação
"score_target": 0.8, //❔propriedade opcional que define o percentual minimo de pixels coincidentes entre needle image e haystack para aprovação. Default 0.5
"debug": false
},
"grayscale": {
"debug": false
},
"bin_threshold": {
"threshold": 180, //❔propriedade opcional que define o valor limiar para binarização da imagem. Default 200
"debug": false
},
"template_xor": {
"mask_size": [ //❔ propriedade opcional que define o tamanho da mascara para aplicação de XOR. Default [10, 10]
30, //altura em pixels
50 //largura em pixels
],
"min_score" : 0.9, //❔ propriedade opcional que define o percentual minimo de pixels coincidentes entre a mascara aplicada sobre needle image e haystack. Default 0.8
"validate": true, //propriedade indicando que esta etapa realizará a aprovação ou reprovação da imagem.
"debug": false
}
}
},
"pattern2.png": {
"timeout": 5,
"delay": 2, //❔ propriedade opcional que define o tempo de espera para iniciar a validação.
"result": null,
"setup": {
"cap_props": {} //se as propriedades para validar a segunda imagem forem iguais as da primeira, pode-se informar um objeto vazio.
},
"steps": {
"stream": {},
"homography": {
"debug": false
},
"hsv_filter": {
"debug": false
},
"template": {
"score_target": 0.5,
"debug": false
},
"grayscale": {
"debug": false
},
"bin_threshold": {
"debug": false
},
"template_xor": {
"validate": true,
"debug": false
}
}
},
"color.png": {
"timeout": 5,
"result": null,
"setup": {
"cap_props": {
"EXPOSURE": {
"cvenum": 15,
"value": 4.0,
"min": 0,
"max": 15,
"negative": true
}
}
},
"steps": {
"stream": {},
"hsv_filter": { //Etapa que aplica um filtro HSV na imagem, excluindo (pintando de preto) tudo que não corresponder ao range informado.
"filter": {
"hMin": 0, //HUE minimo
"sMin": 0, //SATURATION minimo
"vMin": 0, //VALUE minimo
"hMax": 14, //HUE maximo
"sMax": 255, //SATURATION maximo
"vMax": 255, //VALUE maximo
"sAdd": 0, //SATURATION adicional
"sSub": 0, //SATURATION subtrativo
"vAdd": 255, //VALUE adicional
"vSub": 0 //VALUE subtrativo
},
"debug": false
},
"template": {
"debug": false
},
"main_color": { //Etapa que extrai a cor predominante, e compara com a cor informada em "expected_color"
"debug": false,
"expected_color": "vermelho", //cores possíveis: 🟥vermelho, 🟧laranja, 🟨amarelo, 🟩verde, 🩳ciano, 🟦azul, 🟪roxo
"validate": true
}
}
}
}
⚠️ Para mais informações, inspecione a implementação nos arquivos do repositório
É póssivel executar alguns algorítmos de forma isolada, esse recurso existe especialmente para desenvolvimento
, onde por vezes é necessário combinar uma série de filtros e configurações para realizar uma validação.
Habilita trackbars para alterar as configurações da camera.
Cada vez que uma configuração for alterada, a imagem será atualizada e será printado no terminal a configuração atual.
Nesse momento é possível copiar o objeto, e colar no .json
do workflow
. O output se parece com isso:
cam props has changed: {'BRIGHTNESS': {'cvenum': 10, 'value': 128.0, 'min': 0, 'max': 255}, 'CONTRAST': {'cvenum': 11, 'value': 32.0, 'min': 0, 'max': 255}, 'SATURATION': {'cvenum': 12, 'value': 126.0, 'min': 0, 'max': 255}, 'GAIN': {'cvenum': 14, 'value': 0.0, 'min': 0, 'max': 255}, 'EXPOSURE': {'cvenum': 15, 'value': 6.0, 'min': 0, 'max': 15, 'negative': True}, 'SHARPNESS': {'cvenum': 20, 'value': 24.0, 'min': 0, 'max': 255}, 'ZOOM': {'cvenum': 27, 'value': -1.0, 'min': 0, 'max': 400}, 'FOCUS': {'cvenum': 28, 'value': -1.0, 'min': 0, 'max': 255}}
Similar ao camera.py
, o hsvfilter.py
possibilita aplicar um filtro HSV E
alterar as configurações da camera.
Também similar ao camera.py
, o hsvfilter.py
printa os valores de filtros e configurações da câmera no terminal (sempre printa a última alteração realizada).
Output:
{'hMin': 82, 'sMin': 198, 'vMin': 159, 'hMax': 114, 'sMax': 255, 'vMax': 255, 'sAdd': 0, 'sSub': 0, 'vAdd': 0, 'vSub': 0, 'trackbar_is_active': True}
Ao executar separadamente o grayscale.py
, abrirá todas as configurações anteriores, e uma nova configuração de Threshold
.
Essa configuração determina o limiar do processo de binarização, etapa responsável por preparar a imagem para template_over_xor
Foi implementado um script para verificar as dependências do projeto. Caso não estejam instaladas ou instaladas na versão incorreta, o script irá resolver baixando e instalando as dependências.
Para isso, basta executar o seguinte método:
import { DepChecker } from "../node_modules/@libs-scripts-mep/inv-img-tool/IIT.js"
const depCheckResult = await DepChecker.checkDependencies()
if (!depCheckResult.success) { throw new Error('Failed dependency check') }
Implementação minimalista para realizar o primeiro contato com a ferramenta. Necessita:
- Abrir o repositório
inv-img-tool
como workspace no VScode (⚠️ não abrir o repositório principal do script como workspace) - Executar manualmente o arquivo
websocket.py
- Ter uma câmera conectada à máquina
- Abrir o arquivo
test/index.html
no navegador - Clique em start, e aponte a camera para a window
Template
que abrirá.