HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpModerate

Finding rectangles in an image

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
imagerectanglesfinding

Problem

So my this class is one in which is used to find rectangles in images that have already been pre-processed. For example the images are to be deskewed, greyscale etc. Following feedback off of various people I have been told to try and conform it to c# coding standards. I have tried to do my best but was wondering what you guys thought. The code is below:

```
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;

namespace Recognition
{
public class OMRRecognition : IDisposable
{
private const int BYTES_PER_PIXEL = 3;

private const int MAX_BLACK_VALUE = 382; // (255 * 3) / 2 rounded down

private const float MIN_ZONE_MULTIPLIER = 0.85f;
private const float MAX_ZONE_MULTIPLIER = 1.15f;

private const float LINE_BROKEN_TOLERANCE = 0.10f;

private bool _bImageOpen;

private int _nBitmapWidth;
private int _nBitmapHeight;

private int _nStride;
private byte[] _baPixels;

private int _nCornerTolerance;
private int _nMaxHorBrokenAmount;
private int _nMaxVertBrokenAmount;
private Size _sExpectedZoneSize;
private Size _sMinZoneSize;
private Size _sMaxZoneSize;

public OMRRecognition()
{
SetZoneSize(new Size(10, 10));
SetCornerTolerance(5);

_bImageOpen = false;
}

public void Dispose()
{
_baPixels = null;

_bImageOpen = false;
}

public void SetZoneSize(Size zoneSize)
{
_sExpectedZoneSize = zoneSize;
_sMinZoneSize = new Size((int)(zoneSize.Width MIN_ZONE_MULTIPLIER), (int)(zoneSize.Height MIN_ZONE_MULTIPLIER));
_sMaxZoneSize = new Size((int)(zoneSize.Width MAX_ZONE_MULTIPLIER), (int)(zoneSize.Height MAX_ZONE_MULTIPLIER));

_nMaxHorBrokenAmount = (int)Math.Ceiling(zoneSize.Width * LINE_BROKEN_TOLERANC

Solution

Naming

Your constants don't follow C# naming conventions. The convention is to use PascalCase.

Additionally you appear to be using Hungarian notation on your private fields, which also is against convention.

Design

Your dispose function does not appear to do any actual disposing that would not be performed by the garbage collector.

You have Setter methods. This is a Java paradigm that is accounted for with Properties in C#.

These two if statements should have their conditions combined:

if (verticalLine.StartPoint.X = (horizontalLine.StartPoint.X - _nCornerTolerance))
                {
                    if (horizontalLine.StartPoint.Y = (verticalLine.StartPoint.Y - _nCornerTolerance))


Code to interfaces

Your method:

private Pixel[] FindTopLeftCorners(Line[] horizontalLines, Line[] verticalLines)


Could easily take two IEnumerable interfaces instead of Line[]. This allows the caller to supply any data structure that supports enumeration (which is all you use those parameters for).

Var

You should use implicit typing when the right-hand side of the assignment makes the type obvious. For example:

Rectangle rect = new Rectangle(pTopLeft.X - 1, pTopLeft.Y - 1, (pTopRight.X - pTopLeft.X) + 2, (pBottomLeft.Y - pTopLeft.Y) + 2);


Should be:

var rect = new Rectangle(pTopLeft.X - 1, pTopLeft.Y - 1, (pTopRight.X - pTopLeft.X) + 2, (pBottomLeft.Y - pTopLeft.Y) + 2);


Generic Exceptions

Don't catch them. You can't handle a generic exception because you don't know what it is. Catch what you know you can handle, leave the rest.

This is a pretty egregious use of exceptions as flow control:

try
        {
            if (!_bImageOpen)
                throw new Exception("An image must be opened first using the 'OpenImage' method!");

            return ExtractZones();
        }
        catch (Exception ex)
        {
            return null;
        }


You throw and immediately catch an exception here, causing a return of null. Instead, return null if the image is not open.

if (!_bImageOpen)
    return null;

Code Snippets

if (verticalLine.StartPoint.X <= (horizontalLine.StartPoint.X + _nCornerTolerance) && verticalLine.StartPoint.X >= (horizontalLine.StartPoint.X - _nCornerTolerance))
                {
                    if (horizontalLine.StartPoint.Y <= (verticalLine.StartPoint.Y + _nCornerTolerance) && horizontalLine.StartPoint.Y >= (verticalLine.StartPoint.Y - _nCornerTolerance))
private Pixel[] FindTopLeftCorners(Line[] horizontalLines, Line[] verticalLines)
Rectangle rect = new Rectangle(pTopLeft.X - 1, pTopLeft.Y - 1, (pTopRight.X - pTopLeft.X) + 2, (pBottomLeft.Y - pTopLeft.Y) + 2);
var rect = new Rectangle(pTopLeft.X - 1, pTopLeft.Y - 1, (pTopRight.X - pTopLeft.X) + 2, (pBottomLeft.Y - pTopLeft.Y) + 2);
try
        {
            if (!_bImageOpen)
                throw new Exception("An image must be opened first using the 'OpenImage' method!");

            return ExtractZones();
        }
        catch (Exception ex)
        {
            return null;
        }

Context

StackExchange Code Review Q#111795, answer score: 10

Revisions (0)

No revisions yet.