好的,作为一个理工生,一般不整那么多花里胡哨的,想知道奇数还是偶数,那就得算算大米到底有多少颗。
高赞确实有类似的设备可以实现这种数大米的功能,但是毕竟这种设备不便宜,现在有工业版本的,那有没有家用版本的。
比如我抓了一小撮大米,然后撒在桌面上,为什么只有一小撮呢?
第一:浪费粮食是不好的
第二:抓太多了大米之间连在一块,得用更复杂的方法,我懒
而一个一个算太慢,能不能用手边的设备来算算到底有多少颗呢?比如我们用手机拍一张照片,像这样。
那么,老规矩,为了方便图像后续处理,我们直接处理成灰度图(其实我后面琢磨了一下,不如去抓 r 通道效果更好,凑合看吧不管了)
然后我们看看背景颜色的灰度值
还有大米的灰度值
直接根据颜色差值设定阈值二值化图像
可以看到,效果不太好,为啥,因为因为背景光照不均匀有些大米内部颜色和背景混色了,一些大米出现了中空的情况,也好办,弄个导数的二值滤波,再来一次,
好,舒服多了,之后就是简简单单判定联通的白色区域了,然后我们标定后,把计数文本弄回原始图像中,可以看到,程序大米数的非常好,一撮大米一共 61 个,灰常准确有效。
应该算是图像 CV 比较入门级的知识点,下次拿去折磨下学生好了.
实验型代码,工程慎用
#include "PainterEngine.h"
px_texture srcTexture;
px_texture dstTexture;
px_void MarkRegion(px_texture* ptexture, px_int x, px_int y,px_color detectcolor, px_color markcolor,px_int *counter)
{
if (x < 0 || y < 0 || x >= ptexture->width || y >= ptexture->height)
{
return 0;
}
if (PX_SURFACECOLOR(ptexture,x,y)._argb.ucolor== detectcolor._argb.ucolor)
{
PX_SURFACECOLOR(ptexture,x,y)=markcolor;
(*counter)++;
MarkRegion(ptexture, x + 1, y, detectcolor, markcolor,counter);
MarkRegion(ptexture, x - 1, y, detectcolor, markcolor,counter);
MarkRegion(ptexture, x, y + 1, detectcolor, markcolor,counter);
MarkRegion(ptexture, x, y - 1, detectcolor, markcolor,counter);
}
}
px_int main()
{
px_int x, y;
px_int riceCount=0;
px_char content[32];
PainterEngine_Initialize(800, 800);
PX_LoadTextureFromFile(mp_static, &srcTexture, "assets/sample.png");
PX_TextureCopy(mp_static, &srcTexture, &dstTexture);
PX_ImageFilter_dBinarization(&dstTexture,160,3);
for ( y= 0; y < dstTexture.height; y++)
{
for ( x = 0; x < dstTexture.width; x++)
{
px_int counter=0;
MarkRegion(&dstTexture, x, y, PX_COLOR(255, 255, 255, 255), PX_COLOR(255, 0, 0, 255),&counter);
if (counter>100)
{
riceCount++;
PX_sprintf1(content,sizeof(content), "rice %1", PX_STRINGFORMAT_INT(riceCount));
PX_FontDrawText(&srcTexture, x, y,PX_ALIGN_LEFTBOTTOM,content,PX_COLOR_RED);
}
}
}
//sum rice
PX_sprintf1(content, sizeof(content), "Rice Count:%1", PX_STRINGFORMAT_INT(riceCount));
PainterEngine_DrawTexture(&srcTexture, 400, 400, PX_ALIGN_CENTER);
PainterEngine_DrawText(0, 0, content, PX_ALIGN_LEFTTOP, PX_COLOR_RED);
}
如果你想问工程上怎么用,非机器学习方法我估计会拿个比较"标准"的大米图形做增强后作为算子去做卷积,当然上机器学习方法也是没问题的,不过对于数数这种事而言必要性不大。