static public double CalcCorrelation(RawImage rawImage, ushort[] prevPixels, Point center, Point prevCenter, Size size) { var pixels = rawImage.GetRawPixels(); int width = rawImage.Width; int WX = size.Width / 2; int WY = size.Height / 2; double median = Median(pixels, width, center, size); double prevMedian = Median(prevPixels, width, prevCenter, size); int n = 0; double sumXY = 0; double sumXX = 0; double sumYY = 0; double sumX = 0; double sumY = 0; for (int dy = -WY; dy <= WY; dy++) { int y1 = center.Y + dy; int y2 = prevCenter.Y + dy; for (int dx = -WX; dx <= WX; dx++) { int x1 = center.X + dx; int x2 = prevCenter.X + dx; double X = pixels[y1 * width + x1] - median; double Y = prevPixels[y2 * width + x2] - prevMedian; sumXY += X * Y; sumXX += X * X; sumYY += Y * Y; sumX += X; sumY += Y; n++; } } double result = (n * sumXY - sumX * sumY) / Math.Sqrt((n * sumXX - sumX * sumX) * (n * sumYY - sumY * sumY)); return(result); }
/*static public StackResult AddStackImages( string filePath, StackItem[] currentStack, short[] darkPixels, bool useJpg ) * { * int[] addedPixels = null; * int width = 0; * int height = 0; * int N = 0; * int dX0 = 0; * int dY0 = 0; * for( int i = 0; i < currentStack.Length; i++ ) { * if( currentStack[i].IsExcluded ) { * continue; * } * Color[] pixels = null; * short[] cfaPixels = null; * if( useJpg ) { * throw new NotImplementedException(); * using( var image = currentStack[i].Image.LoadThumbnail() ) { * pixels = currentStack[i].Image.GetThumbnailRgbPixels(); * width = image.Width; * height = image.Height; * } * } else { * throw new NotImplementedException(); * cfaPixels = currentStack[i].Image.GetCfaPixels(); * width = currentStack[i].Image.Width; * height = currentStack[i].Image.Height; * if( darkPixels != null ) { * for( int j = 0; j < cfaPixels.Length; j++ ) { * cfaPixels[j] -= darkPixels[j]; * } * for( int y = 2; y < height - 2; y++ ) { * for( int x = 2; x < width - 2; x++ ) { * int j = y * width + x; * if( darkPixels[j] > 350 ) { * cfaPixels[j] = (short)( ( cfaPixels[j - 2] + cfaPixels[j + 2] + * cfaPixels[j - width] + cfaPixels[j + width] ) / 4 ); * } * } * } * } * } * * if( addedPixels == null ) { * dX0 = currentStack[i].Offset.X; * dY0 = currentStack[i].Offset.Y; * if( useJpg ) { * addedPixels = new int[3 *width * height]; * for( int y = 0; y < height; y++ ) { * for( int x = 0; x < width; x++ ) { * Color c = pixels[y * width + x]; * addedPixels[3 * ( y * width + x ) + 0] = c.R; * addedPixels[3 * ( y * width + x ) + 1] = c.G; * addedPixels[3 * ( y * width + x ) + 2] = c.B; * } * } * } else { * addedPixels = new int[width * height]; * for( int y = 0; y < height; y++ ) { * for( int x = 0; x < width; x++ ) { * addedPixels[y * width + x] = cfaPixels[y * width + x]; * } * } * * } * } else { * int dX = currentStack[i].Offset.X - dX0; * int dY = currentStack[i].Offset.Y - dY0; * if( !useJpg ) { * dX *= 2; * dY *= 2; * } * for( int y = 0; y < height; y++ ) { * for( int x = 0; x < width; x++ ) { * if( x + dX > 0 && x + dX < width && y + dY > 0 && y + dY < height ) { * if( useJpg ) { * Color c = pixels[( y + dY ) * width + x + dX]; * addedPixels[3 * ( y * width + x ) + 0] += c.R; * addedPixels[3 * ( y * width + x ) + 1] += c.G; * addedPixels[3 * ( y * width + x ) + 2] += c.B; * } else { * addedPixels[y * width + x] += cfaPixels[( y + dY ) * width + x + dX]; * } * } * } * } * } * N++; * } * return new StackResult( width, height, addedPixels, N, !useJpg ); * }*/ /*static public Color LocalSky( IImage image, Point p ) * { * int width = image.LoadThumbnail().Width; * Color[] pixels = image.GetThumbnailRgbPixels(); * uint[] countsR = new uint[256]; * uint[] countsG = new uint[256]; * uint[] countsB = new uint[256]; * uint count = 0; * int N = 25; * for( int dy = -N; dy <= N; dy++ ) { * for( int dx = -N; dx <= N; dx++ ) { * int offset = ( p.Y + dy ) * width + p.X + dx; * countsR[pixels[offset].R]++; * countsG[pixels[offset].G]++; * countsB[pixels[offset].B]++; * count++; * } * } * int resultR = 0; * uint total = 0; * for( int i = 0; i < countsR.Length; i++ ) { * total += countsR[i]; * if( 2 * total >= count ) { * resultR = i; * break; * } * } * int resultG = 0; * total = 0; * for( int i = 0; i < countsG.Length; i++ ) { * total += countsG[i]; * if( 2 * total >= count ) { * resultG = i; * break; * } * } * int resultB = 0; * total = 0; * for( int i = 0; i < countsB.Length; i++ ) { * total += countsB[i]; * if( 2 * total >= count ) { * resultB = i; * break; * } * } * return Color.FromArgb( resultR, resultG, resultB ); * }*/ static public Point RefineCenter(RawImage rawImage, Point center, Size size) { var pixels = rawImage.GetRawPixels(); int width = rawImage.Width; /*PointF current = new PointF( center.X, center.Y ); * while( true ) { * double ddx = center.X - current.X; * double ddy = center.Y - current.Y; * double sumX = 0.0; * double sumY = 0.0; * double sum = 0.0; * int N = 17; * for( int dy = -N; dy <= N; dy++ ) { * for( int dx = -N; dx <= N; dx++ ) { * double s = pixels[( center.Y + dy ) * width + center.X + dx]; * if( dy == -N ) { * s *= 0.5 + ddy; * } * if( dy == N ) { * s *= 0.5 - ddy; * } * if( dx == -N ) { * s *= 0.5 + ddx; * } * if( dx == N ) { * s *= 0.5 - ddx; * } * sumX += ( dx + ddx ) * s; * sumY += ( dy + ddy ) * s; * sum += s; * } * } * double dX = sumX / sum; * double dY = sumY / sum; * current.X += (float) dX; * current.Y += (float) dY; * int X = (int) Math.Round( current.X ); * int Y = (int) Math.Round( current.Y ); * if( Math.Abs( dX ) < 0.001 && Math.Abs( dY ) < 0.001 ) { * return new Point( X, Y ); * } * center.X = X; * center.Y = Y; * } * return new Point();*/ int WX = size.Width / 2; int WY = size.Height / 2; Point current = new Point(center.X, center.Y); int run = 0; while (true) { double median = Median(pixels, width, current, size); double sumLdX = 0; double sumLdY = 0; double sumL = 0; for (int dy = -WY; dy <= WY; dy++) { int y = current.Y + dy; for (int dx = -WX; dx <= WX; dx++) { int x = current.X + dx; double L = pixels[y * width + x] - median; if (L > 0) { sumLdX += L * dx; sumLdY += L * dy; sumL += L; } } } double dX = sumLdX / sumL; double dY = sumLdY / sumL; current.X += (int)Math.Round(dX); current.Y += (int)Math.Round(dY); if (run++ > 1) { break; } } return(current); }