Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to speed up my color thresholding in C#
    primarykey
    data
    text
    <p>I'm working on tracking objects based on color and I was using EmguCV library to threshold my color image to binary black and white image. Thresholding itself was quite fast, 50ms on 320x240 image. I'm using RG Chromaticity color space, so there are some necessarily calculations.</p> <p>Now I'm trying to speed it up using pointers, but the result is very similar with what I did with emguCV (around 50ms per image).</p> <p>I want to ask, if there is some expert who can help me, what I am doing wrong. Here is my short code snippet of my color thresholding implementation. It's based on this one <a href="http://www.bobpowell.net/onebit.htm" rel="nofollow">http://www.bobpowell.net/onebit.htm</a>.</p> <pre><code>public static Bitmap ThresholdRGChroma(Bitmap original, double angleMin, double angleMax, double satMin, double satMax) { Bitmap bimg = new Bitmap(original.Width, original.Height, PixelFormat.Format1bppIndexed); BitmapData imgData = original.LockBits(new Rectangle(0, 0, original.Width, original.Height), ImageLockMode.ReadOnly, original.PixelFormat); BitmapData bimgData = bimg.LockBits(new Rectangle(0, 0, bimg.Width, bimg.Height), ImageLockMode.ReadWrite, bimg.PixelFormat); int pixelSize = 3; double r, g, angle, sat; unsafe { byte* R, G, B; byte* row; int RGBSum; for (int y = original.Height - 1; y &gt;= 0; y--) { row = (byte*)imgData.Scan0 + (y * imgData.Stride); for (int x = original.Width - 1; x &gt;= 0; x--) { // get rgb values B = &amp;row[x * pixelSize]; G = &amp;row[x * pixelSize + 1]; R = &amp;row[x * pixelSize + 2]; RGBSum = *R + *G + *B; if (RGBSum == 0) { SetIndexedPixel(x, y, bimgData, false); continue; } //calculate r ang g for rg chroma color space r = (double)*R / RGBSum; g = (double)*G / RGBSum; //and angle and saturation angle = GetAngleRad(r, g) * (180.0 / Math.PI); sat = Math.Sqrt(Math.Pow(g, 2) + Math.Pow(r, 2)); //conditions to set pixel black or white if ((angle &gt;= angleMin &amp;&amp; angle &lt;= angleMax) &amp;&amp; (sat &gt;= satMin &amp;&amp; sat &lt;= satMax)) SetIndexedPixel(x, y, bimgData, true); else SetIndexedPixel(x, y, bimgData, false); } } } bimg.UnlockBits(bimgData); original.UnlockBits(imgData); return bimg; } private unsafe static void SetIndexedPixel(int x, int y, BitmapData bmd, bool pixel) { int index = y * bmd.Stride + (x &gt;&gt; 3); byte* p = (byte*)bmd.Scan0.ToPointer(); byte mask = (byte)(0x80 &gt;&gt; (x &amp; 0x7)); if (pixel) p[index] |= mask; else p[index] &amp;= (byte)(mask ^ 0xff); } private static double GetAngleRad(double x, double y) { if (x - _rgChromaOriginX == 0) return 0.0; double angle = Math.Atan((y - _rgChromaOriginY) / (x - _rgChromaOriginX)); // 10ms if (x &lt; _rgChromaOriginX &amp;&amp; y &gt; _rgChromaOriginY) angle = angle + Math.PI; else if (x &lt; _rgChromaOriginX &amp;&amp; y &lt; _rgChromaOriginY) angle = angle + Math.PI; else if (x &gt; _rgChromaOriginX &amp;&amp; y &lt; _rgChromaOriginY) angle = angle + 2 * Math.PI; return angle; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload