上一节,我们分清了主次矛盾,并搞定了主要矛盾(去掉黄色的字),这一节解决次要矛盾(矩形色带)。
我们的想法如图:
1,我们找到稳定黄色的最左边,最右边两点,画两条竖线,竖线高度10,根据这两条竖线,分别向外拉伸10条横线。代码如下:
for (int i = 240; i <480; i++)
{
byte fugair = 0; byte fugaig = 0; byte fugaib = 0;
byte fugai = 0;
for (int j = 0; j < 640; j++)
{
int n = i * ww + j;
float hue = 0;
RGB2HSLTest(rgbValues[4 * n + 2], rgbValues[4 * n + 1], rgbValues[4 * n], ref hue);
if (hue > 35 && hue < 85 )//,黄色范围给的比较宽泛
{//黄色
//新增,寻找黄色字50-63外接矩形202412130850
if (hue > 50 && hue < 63)//黄色收窄
{
if (j < 找最小) { 找最小 = j ; 存黄色始末[0].X=找最小 ;存黄色始末[0].Y=i ;}
if (j > 找最大) { 找最大 = j ; 存黄色始末[1].X = 找最大; 存黄色始末[1].Y = i ; }
}
rgbValues[4 * n + 2] = (byte)(rgbValues[4 * n + 2 - 4 * ww] / 2 + fugair / 2);
rgbValues[4 * n + 1] = (byte)(rgbValues[4 * n + 1 - 4 * ww] / 2 + fugaig / 2);
rgbValues[4 * n] = (byte)(rgbValues[4 * n - 4 * ww] / 2 + fugaib / 2);
}else{......}
2,存黄色始末[0]就是黄色最左点,存黄色始末[1]就是黄色最右点。
根据这两点,向外各画出十条直横线线,找到穿越点,我们目的是找到边界,即线A和B。如图:
代码如下:
Point[] 左侧穿越点 = new Point[10]; int b= 0;
for (int xy = 存黄色始末[0].Y - 5; xy < 存黄色始末[0].Y + 5; xy++)
{
for (int j = 存黄色始末[0].X; j >0; j--)//
{
int n = xy * 640 + j;
if (Math.Abs(glob_buffer8[n] - glob_buffer8[n - 1]) > 10)
{
左侧穿越点[b].X = j;
左侧穿越点[b].Y = xy;
break;
}
}
b++;
}
Point[] 右侧穿越点 = new Point[10]; int a = 0;
for (int xy = 存黄色始末[1].Y - 5; xy < 存黄色始末[1].Y + 5; xy++)
{
for (int j = 存黄色始末[1].X; j < 640; j++)//
{
int n = xy * 640+ j;
//找灰度化大于10的点
if (Math.Abs(glob_buffer8[n] - glob_buffer8[n - 1]) > 10)
{
右侧穿越点[a].X = j;
右侧穿越点[a].Y = xy;
break;
}
}
a++;
}
3,利用a竖线和b竖线的起点,各往后退3个像素,往上做垂线,找到色带水平线cd,会找到c.y和d.y值,如果相差小于2个像素,我们就认为色带水平线确认了。如图:
代码如下:
Point[] 向上穿越点 = new Point[2];
向上穿越点[0].X = 左侧穿越点[0].X+3; 向上穿越点[0].Y = 左侧穿越点[0].Y;
向上穿越点[1].X= 右侧穿越点[0].X-3; 向上穿越点[1].Y= 右侧穿越点[0].Y;
int y上界 = 0;
int y上界1 = 0;
for (int xy = 向上穿越点[0].Y; xy >0; xy--)
{
int n = xy * 640 + 向上穿越点[0].X;
if (Math.Abs(glob_buffer8[n] - glob_buffer8[n - 640]) > 10)
{
y上界 = xy;
break;
}
}
for (int xy = 向上穿越点[1].Y; xy > 0; xy--)
{
int n = xy * 640 + 向上穿越点[1].X;
if (Math.Abs(glob_buffer8[n] - glob_buffer8[n - 640]) > 10)
{
y上界1 = xy;
break;
}
}
if (Math.Abs(y上界1 - y上界) <= 2)
{
//ok,找到矩形色带上界
}
else
{
return;
}
4,色带矩形的高有一个经验值118.所以这个色带矩形在视频中有变化,我们有了自动化应对的方法。我们前面也说过了,色带矩形比其他灰度相比,少了50,现在色带矩形中所有像素全部加上50,就ok了。
看到我们上面红色return了没有,如果矩形估计失败(背景出现一堆学生),色带矩形还会在,但黄色还是稳定处理过了。
// ( 消除色带矩形 )
for (int i =左侧穿越点[0].X; i < 右侧穿越点[0].X; i++)
for (int j = y上界 ; j < y上界 +118; j++)
{
int temp = j * 640 + i;//原方法
rgbValues[temp * 4] = (byte)(rgbValues[temp * 4] + 50 > 255 ? 255 : rgbValues[temp * 4] + 50);
rgbValues[temp * 4 + 1] = (byte)(rgbValues[temp * 4 + 1] + 50 > 255 ? 255 : rgbValues[temp * 4 + 1] + 50);
rgbValues[temp * 4 + 2] = (byte)(rgbValues[temp * 4 + 2] + 50 > 255 ? 255 : rgbValues[temp * 4 + 2] + 50);
}
这个改进型原版,肯定比原版自适应性好很多!