我正在使用Emgu CV 2.4.2,并希望执行以下算法:
我已经完成了步骤1-2,并使用BGStatModel提取了blob。我得到的结果是:
Blob图片
我想得到垂直投影中局部极小值的像素位置。在得到它之后,我想要分割这个块,然后像这样画出矩形:
垂直投影图
我试图通过检查blob区域中的每个像素来获得局部极小值的像素位置,但是它使我的应用程序运行得非常慢。这是我的密码:
Point minPix = new Point(0,0);
//copy the foreground frame
Image<Gray, Byte> foreFrame_copy = foreFrame.Copy();
//find the contour
Contour<Point> contours = foreFrame.FindContours(
CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
RETR_TYPE.CV_RETR_EXTERNAL);
//looping every contour
while (contours != null)
{
double PPixel = contours.Area;
if (PPixel >= 1400)
{
//get the contour width
WR = contours.BoundingRectangle.Width;
//divide the contour using estimated pixel position
Num = Convert.ToInt32(WR / 40);
if (Num > 1)
{
//save the estimated pixel position for ROI in arraylist
ArrayList XList = new ArrayList();
for (int i = 1; i <= Num; i++)
{
int x = i * WR / Num;
XList.Add(x);
}
//get the estimated pixel position
foreach (int pos in Xlist)
{
//roiWidth= 10px
int roiWidth = (pos-5) + (pos+5);
//roiHeight= 20px
int roiHeight = 20;
int pixValue = 0;
//STEP 2: set the ROI to speed up computation
foreFrame_copy.ROI = new Rectangle(contours.BoundingRectangle.X, contours.BoundingRectangle.Y, roiWidth, roiHeight);
for (int i = (pos-5); i < roiWidth; i++)
{
for (int j = (pos-5); j < (pos+5); j++)
{
pixValue = foreFrame_copy.Data[i, j, 0];
//find the white pixel
if (pixValue == 255) {
//find the position of minimum pixel
if (j < j-1) {
minPix.X = i;
minPix.Y = j;
}
}
}
}
}
}
//draw the red rectangle
estimatedFrame.Draw(contours.BoundingRectangle, new Bgr(Color.Red), 1);
contours = contours.HNext;
}
else
{
contours = contours.HNext;
}
}
//show frame in framebox
blobBox.Image = foreFrame_copy;
estimatedBox.Image = estimatedFrame;请帮助我如何做步骤2-5以最快的方式使用Emgu简历.如果有人详细介绍这三个步骤和一些代码,我将非常感激。。
谢谢你,大卫
发布于 2012-12-12 20:38:12
好的,这个问题现在变得更清楚了。就我个人而言,我同意mmgp用户的意见,因为由于缺乏通用性,您所引用的文件并不是很好。它是为一个非常特殊的场景编写的,并且对受控环境有一些很强的假设。
我为您提供了一种计算垂直和水平投影以及绝对最大值作为良好起点的方法。
private void ComputeProjections(Image<Bgr, byte> inputImage)
{
Image<Gray, Byte> inputGrayImage = inputImage.Convert<Gray, Byte>();
Matrix<float> imgMatHorizontal = new Matrix<float>(inputGrayImage.Height, 1, 1);
Matrix<float> imgMatVertical = new Matrix<float>(1, inputGrayImage.Width, 1);
inputGrayImage.Reduce<float>(imgMatHorizontal, REDUCE_DIMENSION.SINGLE_COL, REDUCE_TYPE.CV_REDUCE_AVG);
inputGrayImage.Reduce<float>(imgMatVertical, REDUCE_DIMENSION.SINGLE_ROW, REDUCE_TYPE.CV_REDUCE_AVG);
double minH, maxH, minV, maxV;
Point minLocH, maxLocH, minLocV, maxLocV;
imgMatHorizontal.MinMax(out minH, out maxH, out minLocH, out maxLocH);
imgMatVertical.MinMax(out minV, out maxV, out minLocV, out maxLocV);
Image<Gray, Byte> maskProvaH = new Image<Gray, byte>(new Size((int)(maxH - minH + 1), imgMatHorizontal.Rows));
Image<Gray, Byte> maskProvaV = new Image<Gray, byte>(new Size(imgMatVertical.Cols, (int)(maxV - minV + 1)));
for (int i = 0; i < imgMatHorizontal.Rows; i++)
maskProvaH.Draw(new CircleF(new PointF((float)(imgMatHorizontal[i, 0] - minH), i), 1f), new Gray(255), 1);
for (int i = 0; i < imgMatVertical.Cols; i++)
maskProvaV.Draw(new CircleF(new PointF(i, (float)(imgMatVertical[0, i] - minV)), 1f), new Gray(255), 1);
inputImage.Draw(new CircleF(new PointF(minLocV.X, minLocH.Y), 2), new Bgr(Color.Green), 1);
//imageBoxProjected.Image = inputGrayImage;
imageBoxHorizProj.Image = maskProvaH;
//imageBoxVerticProj.Image = maskProvaV;
}如果您对查找本地极大值感兴趣,如参考文件中的那样,您可以开始实现一个简单的局部极大搜索,例如(水平投影代码):
List<Point> localMaxima = new List<Point>();
imgMatHorizontal.MinMax(out minH, out maxH, out minLocH, out maxLocH);
Image<Gray, Byte> maskProvaH = new Image<Gray, byte>(new Size((int)(maxH - minH + 1), imgMatHorizontal.Rows));
for (int i = 0; i < imgMatHorizontal.Rows; i++)
maskProvaH.Draw(new CircleF(new PointF((float)(imgMatHorizontal[i, 0] - minH), i), 1f), new Gray(255), 1);
//// Absolute Horizontal Projection Maxima Drawing
//inputGrayImage.Draw(new Cross2DF(new PointF(maxLocH.X, maxLocH.Y), 2, 2), new Gray(255), 2);
// Local maximas search
for (int i = imgMatHorizontal.Rows - 2; i > 1; i--)
{
float prev = imgMatHorizontal[i + 1, 0];
float curr = imgMatHorizontal[i, 0];
float next = imgMatHorizontal[i - 1, 0];
if (curr >= prev && curr >= next)
localMaxima.Add(new Point((int)curr, i));
}这段代码来自我在youtube上的一个演示:
基于投影的人脸特征演示
其余的步骤都是相当琐碎的,您可以根据您的需要调整它,或者遵循本文中建议的交叉比率阈值。
https://stackoverflow.com/questions/13808204
复制相似问题