
54/54 的报告
在工作接近尾声时,得出了“两个魔方都是 54/54”的结果。可是新拍的照片却总是出错。
看了代码才发现是有原因的。代码中有一条路径:只要照片的宽高与测试用照片相同,就直接放入保存好的正确展开图。正版魔方最后去掉了这条路径,但韩国发售版的两组照片还保留着。那个 54/54 是没有读取照片像素就得到的。
重新测量的识别率
项目本身保持不动,我们在副本中改成只能关掉这条路径,然后重新测量。正确答案是我亲手拼对后提供的展开图,不会转动的中心 6 格不计,按 48 格统计。
- 韩国发售版 A(最初调好的照片):42/48(88%)
- 韩国发售版 B(新打乱后拍的照片):17/48(35%)
- 正版手机照片:28/48(58%)
- 正版干净的高分辨率照片:32/48(67%)
每张照片都做了 12 种变换后输入:亮度 ±15%、色温、±4° 旋转、0.8 倍和 1.25 倍缩放、JPEG 压缩、添加边距、调换照片顺序。只旋转 4°,韩国发售版 A 就降到 34 格,B 降到 8 格。这说明贴合已知答案照片的阈值在别的照片上行不通。只有最初调好的照片分数高,同一个魔方重新打乱后拍的照片只有 35%。正版在 60% 左右。
48 次运行的结果中,没有一个展开图通过规则检查。现在读取照片之后,必须由人亲手修正错误的格子,才能进入求解。
错误格子的种类

- 只要转动面就正确的格子:面找对了,但旋转了 90° 或 180° 后贴上去的情况。正版和韩国发售版 B 各有 8 格。
- 颜色错误的格子:即使转动面也不对的格子。正版经常把绿↔蓝、橙↔红、黄↔白读反,韩国发售版则经常把白色和橙色读成红色。
测试答案也是错的

正版测试代码中写入的答案,与我亲自提供的答案在 48 格中有 26 格不同。两者都能通过规则检查,也都能解开。但照片中的魔方只是稍微打乱过的状态,所以 9 步就能解开的那个才符合实物。
规则检查只看“这是不是一个能拼出来的魔方”,并不知道它是否与照片一致。这是 AI 只为了让规则和求解对得上而重新确定答案的结果,用这个答案来评分,同一张照片会得到 42%。
求解够用吗
只要符合规则,Kociemba 总能在 22 步以内解开。只要识别正确,求解部分现在就足够了。只是它不是训练出来的模型,而是搜索算法,所以解法与人背的步骤不同。原本想展示分步人类解法的逐层求解器只能解开 10%。如果像我卡在第 8 步时那样用来学习,这部分也需要改进。
要提高识别率
接下来要尝试的事情:
- 不再拍两张斜角照片,而是在相机画面上显示 3×3 引导线,一个面一个面地正面拍六次。面方向错误和透视问题都会消失。很多魔方求解应用都采用这种方式。
- 不用固定阈值,而是以该魔方中心 6 格的颜色为基准,选择最接近的颜色。魔方和光照变化时,基准也会随之变化。
- 为每一格保留第一和第二候选颜色,选出能通过规则检查和求解的组合。
- 已知答案的照片现在只有四组。用两个魔方改变光照和角度收集几十组,并用从未针对其调整过的照片来评分。
发布
在应用商店搜了一下,类似的魔方应用有 20 多个。有点泄气,但既然开始了,就打算做到底。
因为目的不是销售,我也考虑过在网站上放 apk 或应用文件。但如果有人把文件调包,所有下载的人都会受害。商店会经过开发者签名和审核,所以打算通过商店发布。
在上架商店之前,还有一些需要整理的事情。
- 现在使用的 Kociemba C 实现(muodov/kociemba)是 GPL-2.0。有观点认为应用商店的条款与 GPL 不兼容,所以自己实现或换成其他许可证的实现会更安全。
- 现在它是 Mac 上的 Qt 桌面应用。要想直接用手机相机拍摄,就必须重新制作 iOS 和安卓的界面。
这一阶段的实际代码
这是照片尺寸相同时放入保存答案的部分。韩国发售版的两组照片还保留着它。
src/CubePhotoReconstructor.cpp
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;
}还有一段代码,在出现特定打乱图案时会额外加分。这些值是为一组测试照片量身调整的。
src/CubePhotoReconstructor.cpp
} 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;下一篇是“4. 完整源代码与使用的工具”。
COMMENTS · CHAPTER 03
54/54 的真相、实际识别率以及发布 评论 0
还没有评论。阅读时有疑问或想补充的内容,欢迎留言。
发表评论前,请用 Google 开始并登记昵称和邮箱。
用 Google 开始