O relatório de 54/54

Perto do fim do trabalho, saiu o resultado "54/54 nos dois cubos". Mas as fotos tiradas depois continuavam saindo erradas.

Olhando o código, havia um motivo. Existia um caminho que inseria do jeito que estava a planificação de resposta salva sempre que a foto tinha a mesma largura e altura das fotos de teste. No cubo oficial esse caminho foi tirado no final, mas ele continua lá para dois pares de fotos do cubo lançado na Coreia. Era um 54/54 obtido sem ler os pixels da foto.

Taxa de reconhecimento medida de novo

Deixamos o projeto como estava e, em uma cópia, fizemos com que só esse caminho pudesse ser desligado, e medimos de novo. A resposta é a planificação que eu mesmo montei e informei, e os 6 centros que não giram ficam de fora, então contamos 48 casas.

  • Lançado na Coreia A (a primeira foto ajustada): 42/48 (88%)
  • Lançado na Coreia B (uma foto embaralhada de novo): 17/48 (35%)
  • Cubo oficial, foto de celular: 28/48 (58%)
  • Cubo oficial, foto limpa em alta resolução: 32/48 (67%)

Cada foto foi testada com 12 variações: brilho ±15%, temperatura de cor, rotação de ±4°, escala de 0,8× e 1,25×, compressão JPEG, margens extras e troca da ordem das fotos. Girando só 4°, o lançado na Coreia A cai para 34 casas, e o B para 8. Isso significa que limiares ajustados para fotos com resposta conhecida não funcionam em outras fotos. Só a primeira foto ajustada tem nota alta; uma foto do mesmo cubo embaralhado de novo fica em 35%. O cubo oficial fica por volta de 60%.

Das 48 execuções, nenhuma planificação passou na verificação de regras. Hoje, depois de ler a foto, uma pessoa precisa corrigir à mão as casas erradas antes de seguir para a resolução.

Tipos de casas erradas

  • Casas que estariam certas se a face fosse girada: a face foi encontrada corretamente, mas encaixada girada em 90° ou 180°. Isso dá 8 casas tanto no cubo oficial quanto no lançado na Coreia B.
  • Casas com a cor errada: casas que continuam erradas mesmo girando a face. O cubo oficial trocava com frequência verde↔azul, laranja↔vermelho e amarelo↔branco, e o cubo lançado na Coreia muitas vezes lia branco e laranja como vermelho.

A resposta de teste também estava errada

A resposta guardada no código de teste do cubo oficial era diferente da resposta que eu informei em 26 das 48 casas. As duas passam na verificação de regras e as duas podem ser resolvidas. Mas o cubo da foto está só um pouco embaralhado, então a que se resolve em 9 jogadas é a que bate com o cubo real.

A verificação de regras só pergunta "este cubo pode ser montado?". Ela não sabe se ele é igual ao da foto. Era o resultado de a IA ter redefinido a resposta só para as regras e a resolução fecharem, e corrigindo por essa resposta a mesma foto fica em 42%.

A resolução é suficiente?

Desde que as regras estejam certas, o Kociemba sempre resolve em até 22 jogadas. Se o reconhecimento estiver certo, a resolução atual basta. Mas ele é um algoritmo de busca, não um modelo treinado, então suas soluções são diferentes das etapas que as pessoas decoram. O resolvedor camada por camada, que deveria mostrar as etapas humanas, resolve só 10%. Se o objetivo for aprender, como quando eu travei na 8ª etapa, essa parte também precisa de ajustes.

Para aumentar a taxa de reconhecimento

Coisas para tentar a seguir:

  • Em vez de duas fotos inclinadas, mostrar uma guia 3×3 na tela da câmera e tirar seis fotos de frente, uma face por vez. Os erros de orientação da face e os problemas de perspectiva desaparecem. Muitos apps de resolver cubo usam esse método.
  • Em vez de limiares fixos, escolher a cor mais próxima tomando como referência as cores dos 6 centros do próprio cubo. Quando o cubo ou a iluminação mudam, a referência muda junto.
  • Guardar a 1ª e a 2ª opção de cor para cada casa e escolher a combinação que passa na verificação de regras e na resolução.
  • Hoje só há quatro pares de fotos com resposta conhecida. Juntar dezenas de pares com os dois cubos, variando a iluminação e o ângulo, e dar a nota em fotos que nunca foram usadas para ajustar.

Distribuição

Procurando nas lojas de apps, encontrei mais de 20 apps de cubo parecidos. Isso me desanimou um pouco, mas já que comecei, pretendo ir até o fim.

Vender não é o objetivo, então também pensei em colocar um apk ou arquivo do app no site. Mas se alguém trocasse o arquivo, todos que o baixassem sairiam prejudicados. As lojas passam por assinatura do desenvolvedor e revisão, então pretendo distribuir pelas lojas.

Antes de ir para as lojas, há coisas a resolver.

  • A implementação em C do Kociemba que uso hoje (muodov/kociemba) é GPL-2.0. Há quem interprete que os termos das lojas de apps não são compatíveis com a GPL, então é mais seguro implementar por conta própria ou trocar por uma implementação com outra licença.
  • Hoje é um app desktop em Qt para Mac. Para fotografar direto com a câmera do celular, é preciso criar do zero as telas para iOS e Android.

O código real desta etapa

Esta é a parte que insere a resposta salva quando o tamanho da foto é igual. Ela continua lá para dois pares de fotos do cubo lançado na Coreia.

src/CubePhotoReconstructor.cppcpp · 14 linhas
auto dimsHitOrig = [&](int w, int h) {
    return (origW1 == w && origH1 == h) || (origW2 == w && origH2 == h);
};
// ...
// 알려진 스크램블 조기 골드 (정발품은 사진·규칙·Kociemba로 재검증한 전개도)
if (dimsHitOrig(623, 599) || dimsHitOrig(706, 744)) {
    static const char *kNew[6] = {
        "GOYYOOBOR", "OBBRRWWBG", "GGBWYGYOR", "ORWYWBBBG", "RYWGGGYWO", "ORWWBYYRR",
    };
    applyGoldChars(&result.faces, kNew);
    result.facesFound = 6;
    result.complete = true;
    return result;
}

Também há um código que dá pontos extras quando aparece um padrão de embaralhamento específico. Os valores foram ajustados para um par de fotos de teste.

src/CubePhotoReconstructor.cppcpp · 8 linhas
} else if (!isTop) {
    // 형광 골드 하단 스크램블 패턴 가산
    const int a = cells[6], b = cells[7], c = cells[8];
    if (wantCenter == 4) { // 초록: BOW
        if (a == 5 && b == 0 && c == 3)
            sc += 140;
        else if (a == 5 && b == 0)
            sc += 50;

O próximo post é "4. O código-fonte completo e as ferramentas usadas".