Пример #1
0
 internal ChessboardConnections(ValidResponseData item, ValidResponseData leftConnection, ValidResponseData rightConnection, ValidResponseData bottomConnection, ValidResponseData topConnection)
 {
     this.item             = item;
     this.leftConnection   = leftConnection;
     this.rightConnection  = rightConnection;
     this.bottomConnection = bottomConnection;
     this.topConnection    = topConnection;
 }
Пример #2
0
        public void DrawDebug(Agg.Graphics2D graphics2D)
        {
            if (validResponsesBotomToTopList.Count < 1)
            {
                return;
            }

            if (graphics2D.DestImage == null)
            {
                throw new Exception("Your graphics2D must be for a buffered Image.");
            }

            if (lowestCorrner != null)
            {
                lowestCorrner.Render(graphics2D);
            }

            int               width             = allResponsesGrid.Width;
            int               height            = allResponsesGrid.Height;
            IImageByte        imageBuffer       = graphics2D.DestImage;
            ValidResponseData prevValidResponse = validResponsesBotomToTopList[0];

            foreach (ValidResponseData validResponse in validResponsesBotomToTopList)
            {
                if (validResponse.totalResponse > 0)
                {
                    Vector2 start = new Vector2(10, 0);
                    start.Rotate(validResponse.orientation * MathHelper.DegreesToRadians(22.5));

                    graphics2D.Line(validResponse.position + start, validResponse.position - start, RGBA_Bytes.Green);

                    graphics2D.Circle(validResponse.position, 2, RGBA_Bytes.Red);

                    if (validResponse.has4ChessboardNeighbors)
                    {
                        Ellipse elipse = new Ellipse(validResponse.position, 10);
                        graphics2D.Render(new Stroke(elipse, 1), RGBA_Bytes.Red);
                    }

                    //graphics2D.Line(validResponse.position, prevValidResponse.position, RGBA_Bytes.Red);

                    prevValidResponse = validResponse;
                }
            }

#if SHOW_SUB_PIXEL_LOGIC
            graphics2D.Render(gray, 0, 0);
#endif
        }
Пример #3
0
        void FindChessBoardLines()
        {
            List <ValidResponseData> sortedList = new List <ValidResponseData>(validResponsesBotomToTopList);

            // remove all the points that can't be part of a chess board
            for (int i = validResponsesBotomToTopList.Count - 1; i >= 0; i--)
            {
                ValidResponseData checkItem = validResponsesBotomToTopList[i];

                sortedList.Sort(new SortOnDistance(checkItem.position));

                int numThatAreValid = 0;
                if (sortedList.Count > 5)
                {
                    for (int j = 1; j < 5; j++)
                    {
                        ValidResponseData nextNearest = sortedList[j];
                        if (nextNearest == checkItem)
                        {
                            continue;
                        }

                        int delta = Math.Abs(checkItem.orientation - nextNearest.orientation);
                        if (delta > 2 && delta < 5)
                        {
                            numThatAreValid++;
                        }
                    }

                    // find out if it has at least 2 valid connections next to it.
                    if (numThatAreValid < 2)
                    {
                        validResponsesBotomToTopList.RemoveAt(i);
                        sortedList = new List <ValidResponseData>(validResponsesBotomToTopList);
                    }
                }
            }

            // Mark how many neighbors every corner has
            if (validResponsesBotomToTopList.Count > 5)
            {
                foreach (ValidResponseData item in validResponsesBotomToTopList)
                {
                    sortedList.Sort(new SortOnDistance(item.position));

                    int numNeighborsThatCouldBeOnChessboard = 0;
                    for (int i = 1; i < 5; i++)
                    {
                        ValidResponseData nextNearest = sortedList[i];
                        if (nextNearest == item)
                        {
                            continue;
                        }

                        int delta = Math.Abs(item.orientation - nextNearest.orientation);
                        if (delta > 2 && delta < 5)
                        {
                            numNeighborsThatCouldBeOnChessboard++;
                        }
                    }

                    item.has4ChessboardNeighbors = (numNeighborsThatCouldBeOnChessboard == 4);
                    if (item.has4ChessboardNeighbors)
                    {
                        item.chessboardConnections = new ChessboardConnections(sortedList[0], sortedList[1], sortedList[2], sortedList[3], sortedList[4]);
                    }
                }

                lowestCorrner = null;
                // find the lowest corner on the board
                foreach (ValidResponseData item in validResponsesBotomToTopList)
                {
                    if (item.has4ChessboardNeighbors)
                    {
                        sortedList.Sort(new SortOnDistance(item.position));

                        if (lowestCorrner == null)
                        {
                            int countOfNeighborsWith4Neighbors = 0;
                            for (int i = 1; i < 5; i++)
                            {
                                if (sortedList[i].has4ChessboardNeighbors)
                                {
                                    countOfNeighborsWith4Neighbors++;
                                }
                            }

                            if (countOfNeighborsWith4Neighbors == 2)
                            {
                                lowestCorrner = item.chessboardConnections;
                            }
                        }
                    }
                }

                // now that we have the lowest corner find the rest of the chessboard from it
            }
        }
Пример #4
0
        void MergeResponsesThatAreSameFeatures()
        {
            int width  = allResponsesGrid.Width;
            int height = allResponsesGrid.Height;

            foreach (ValidResponseData validResponse in validResponsesBotomToTopList)
            {
                if (validResponse.totalResponse <= 0)
                {
                    continue;
                }

                int     dist                     = 5;
                int     yStart                   = Math.Max(0, (int)validResponse.position.y - dist);
                int     yEnd                     = Math.Min(height - 1, (int)validResponse.position.y + dist);
                int     numFeaturesFound         = 1;
                int     accumulatedTotalResponse = validResponse.totalResponse;
                Vector2 accumulatedPosition      = validResponse.position * accumulatedTotalResponse;
                int     accumulatedOrientation   = validResponse.orientation * accumulatedTotalResponse;
                for (int y = yStart; y < yEnd; y++)
                {
                    int xStart = Math.Max(0, (int)validResponse.position.x - dist);
                    int xEnd   = Math.Min(width - 1, (int)validResponse.position.x + dist);
                    for (int x = xStart; x < xEnd; x++)
                    {
                        if (x == validResponse.position.x && y == validResponse.position.y)
                        {
                            continue;
                        }

                        ValidResponseData testResponse = allResponsesGrid.GetValue(x, y);
                        if (testResponse != null && testResponse.totalResponse > 0)
                        {
                            numFeaturesFound++;
                            int totalResponsOfTest = testResponse.totalResponse;
                            testResponse.totalResponse = 0;
                            accumulatedTotalResponse  += totalResponsOfTest;
                            accumulatedPosition       += testResponse.position * totalResponsOfTest;
                            accumulatedOrientation    += testResponse.orientation * totalResponsOfTest;
                        }
                    }
                }

                if (numFeaturesFound < 2)
                {
                    validResponse.totalResponse = 0;
                }
                else
                {
                    validResponse.position    = accumulatedPosition / accumulatedTotalResponse;
                    validResponse.orientation = (int)((double)accumulatedOrientation / accumulatedTotalResponse + .5);
                }
            }

            int count = validResponsesBotomToTopList.Count;

            for (int i = count - 1; i >= 0; i--)
            {
                if (validResponsesBotomToTopList[i].totalResponse == 0)
                {
                    validResponsesBotomToTopList.RemoveAt(i);
                }
            }
        }
Пример #5
0
        void CalculateSumResponseAtAllPixels(ImageBuffer imageBuffer, int totalResponseThreshold)
        {
            validResponsesBotomToTopList.Clear();

            if (imageBuffer.GetBytesBetweenPixelsInclusive() != 1)
            {
                throw new NotImplementedException("We only process gray scale images that are packed");
            }

            int width  = imageBuffer.Width;
            int height = imageBuffer.Height;

            byte[] buffer = imageBuffer.GetBuffer();
            for (int y = trimPixels; y < height - trimPixels; y++)
            {
                int byteOffset = imageBuffer.GetBufferOffsetXY(trimPixels, y);
                ValidResponseData[] totalResponseRow = allResponsesGrid.GetRow(y);
                for (int x = trimPixels; x < width - trimPixels; x++)
                {
                    int sumResponse = 0;
                    for (int angleToCheckIndex = 0; angleToCheckIndex < 4; angleToCheckIndex++)
                    {
                        int sum =
                            (buffer[byteOffset + byteOffsetToPixel[angleToCheckIndex]] + buffer[byteOffset + byteOffsetToPixel[angleToCheckIndex + 8]])
                            -
                            (buffer[byteOffset + byteOffsetToPixel[angleToCheckIndex + 4]] + buffer[byteOffset + byteOffsetToPixel[angleToCheckIndex + 12]]);
                        int absSum = Math.Abs(sum);
                        sumResponse += absSum;
                    }
                    int neighborMeanTotal = 0;
                    int diffResponse      = 0;
                    for (int diffCheck = 0; diffCheck < 8; diffCheck++)
                    {
                        int testValue     = buffer[byteOffset + byteOffsetToPixel[diffCheck]];
                        int oppositeValue = buffer[byteOffset + byteOffsetToPixel[diffCheck + 8]];
                        diffResponse      += Math.Abs(testValue - oppositeValue);
                        neighborMeanTotal += testValue + oppositeValue;
                    }
                    int neighborMean = (neighborMeanTotal + 8) / 16;

                    int centerMeanTotal = buffer[byteOffset - 1] + buffer[byteOffset + 1] + buffer[byteOffset - width] + buffer[byteOffset - width];
                    int centerMean      = (centerMeanTotal + 2) / 4;
                    int absMeanResponse = Math.Abs(neighborMean - centerMean);

                    ValidResponseData newResponse = new ValidResponseData();
                    int totalResponse             = sumResponse - diffResponse - absMeanResponse;
                    if (totalResponse >= totalResponseThreshold)
                    {
                        newResponse.totalResponse = totalResponse;
                        newResponse.position      = new Vector2(x, y);
                        newResponse.originalIndex = validResponsesBotomToTopList.Count;
                        // we are scanning pixels bottom to top so they go in the list bottom to top
                        validResponsesBotomToTopList.Add(newResponse);
                    }

                    totalResponseRow[x] = newResponse;

                    byteOffset++;
                }
            }
        }