上一节,完成了两个自己比较满意的设计,你是否看到机器视觉工作中图像处理的影子,是的,他已经深深的影响了你的潜意识,我们在实时取像中的令人咂舌的表演,实质都是每一关键静态时光研究努力的成果,如果这种努力叫做手动,那么实时取像时的表演我们定义为自动,其实这本来是一种创造创新,只不过你未感受到罢了,人工智能的大数据学习以及和人下棋的每一步判断,仍然是这种意识的延伸,时光光怪陆离,瞬息万变,如果你不努力地在时光中去争取那关键片刻(自由),那么,等待你的一定是无能为力地被时光(实时)所左右,即所谓,乱花渐欲迷人眼。静态绿色的慢时光,终会变成收获的橙黄,一年好景君须记,恰是橙黄橘红时(改了苏轼的诗)。
我们距离实时表演还有几步,首先是一个(wu)音的波形特征头的制作,接着前头的工作,先秀一个,list单中含有特征头的三段960字节波形:
截取的很相似的三段wu音,如果你觉得第三段特征更好,我们就在第三段中取特征,如果第一段特征更好,那么通过‘删除不满意’按钮,只保留第一段来取特征,下来我们看看‘cutoffsetwave(截取960字节特征波)’,他有一个offset参数,通过设置这个参数,我们截取的960字节特征波,可以在1920字节冻住波形中游走选择。代码如下:
private void btoffsetwave_Click(object sender, EventArgs e)
{
int tempOffset=Convert.ToInt32(tboffset.Text);
if(m_RecI-tempOffset<=0)return;
lstaImg.RemoveAt(lstaImg.Count - 1);
byte[] tempbt=new byte[960];
int d = 0;
int I=m_RecI - tempOffset;
for (int c = I; c < I+ 960; c++)
{
tempbt[c - I] = bt[I + d];
d++;
}
lstaImg.Add(tempbt);
}
而‘特征头’按钮,只选取256字节尺度的波形,他可以在选定的960字节波形中游走,offset与前面意义相同,是否有一种高数中求极限逼近的感觉?登山的路越来越窄,险峰越来越近,人生的拐点也将到来。看代码: byte[] Matchbt = null;
private void btfeatureHeader_Click(object sender, EventArgs e)
{
int tempOffsetH = Convert.ToInt32(tbheaderOffs.Text);
int tempOffsetHL = Convert.ToInt32(tbHeaderL.Text);
// byte[]
Matchbt = new byte[tempOffsetHL];
int d = 0;
for (int c = tempOffsetH; c < tempOffsetH + tempOffsetHL; c++)
{
Matchbt[c - tempOffsetH] = lstaImg[lstaImg.Count - 1][tempOffsetH + d];
d++;
}
}////////////////////////////////截取图如下:
我们涂抹了不必要的影响。看到了吧,上面的一模一样的两幅图,我们如何显示一幅256字节的波形图,在‘传递对面’按钮中,代码秀出来: private void chuandi_Click(object sender, EventArgs e)
{
btload = new byte[256];
if (Matchbt != null)
{
btload = Matchbt;
drawload2scale(256, btload, pictureBoxloadmatch);
}
}/////////////////////////////////////////
public void drawload2scale(int ww, byte[] loadmatch, PictureBox pb)
{
int _RoiW = ww;
int _RoiH = 256;
pb.Size = new System.Drawing.Size(ww, 256);
//顯示
byte[] cutvaluesm = new byte[_RoiW * _RoiH * 3];
int bytesm = _RoiW * _RoiH * 3;
Bitmap cutPic24m = new Bitmap(_RoiW, _RoiH, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
BitmapData _cutPicm = cutPic24m.LockBits(new Rectangle(0, 0, _RoiW, _RoiH), ImageLockMode.ReadWrite,
cutPic24m.PixelFormat);
IntPtr ptrm = _cutPicm.Scan0;//得到首地址
// int n = 0;
for (int i = 0; i < _RoiH; i++)//图像复原,即由8位图变成24位图像
{
for (int j = 0; j < _RoiW; j++)
{
int m = 3 * (i * _RoiW + j);
cutvaluesm[m] = 0;
cutvaluesm[m + 1] = 0;
cutvaluesm[m + 2] = 0;
}
}
if (loadmatch != null)
for (int j = 0; j < _RoiW; j++)
{
int m = 3 * ((loadmatch[j]) * _RoiW + j);
cutvaluesm[m] = 0;
cutvaluesm[m + 1] = 0;
cutvaluesm[m + 2] = 255;
}
System.Runtime.InteropServices.Marshal.Copy(cutvaluesm, 0, ptrm, _RoiH * _RoiW * 3);
cutPic24m.UnlockBits(_cutPicm);
pb.Image = cutPic24m;
}//////////////////////////////////////////////////
在256字节波形图中,我们满意的只有104字节位置,128字节的一个特征头尺度(请看图),到这里,特征头(wu音)制作完成,趁着小喜悦,我们去找(匹配)一把,下面的代码是最原始的图像识别匹配技术(很像在文本中找关键字),先看找到的效果图:
看到了吧,一个小黄色的点(关于显示这个匹配的小黄点的代码,前面未解释,去找一找),在第三段960字节特征波104位置处,为什么是104?在你制作中,可以看到。你还可以在第二段,第一段中去找一找,点击按钮‘删除不满意’,点击按钮‘在lstaimg中寻找一个尺度’,如果能找到,说明尺度选择ok,否则,你需要重新制作所谓的特征头。代码如下:
private void 尺度匹配_Click(object sender, EventArgs e)
{
int minval = 3000;//门槛的应用
int index = -1;
int onescaleL = Convert.ToInt32(tb尺度L.Text);
if (MatchbtoneScale != null && lstaImg.Count != 0)
for (int i = 0; i < 384; i++)
{
int sum = 0;
for (int j = 0; j < onescaleL; j++)
{
int child = Math.Abs(MatchbtoneScale[j] - lstaImg[lstaImg.Count - 1][i + j]);
sum += child;
}
if (sum < minval)//与门槛值比较
{
minval = sum;
index = i;
}
}
tb尺度He.Text = minval.ToString();
tb尺度inwave.Text = index.ToString();
pictureBoxStaticImg.Invalidate();
}
好,够一壶了,回头我们再续保存特征头,加载特征头,以及声音(wu音)识别响应usb摄像头图像的缩放,或者响应开关灯,或者响应关电脑(这个给自己的孩子秀了一把,影响嘛!无处不在)。
可以思考一个问题,三段960字节特征波能否使用归一化思想,统一在一个幅度内,这样更有利于匹配识别,不要跟我要代码,我也没有!没有实现。
注:以上不加说明,均是c#实现,xp系统,富士通t901硬件(i5处理器),vs2010或vs2013
待续(慢慢来!...........)每天一点小改变☺