public class CameraImgData {
private int R_THRESHOLD = 100;
private int G_THRESHOLD = 100;
private int B_THRESHOLD = 100;
int pWidth = 40;
int pHeight = 350; private String filename;
private Bitmap img;
private Graphics gfxImg;
private int[,] R;
private int[,] RRaw;
private int[,] G;
private int[,] GRaw;
private int[,] B;
private int[,] BRaw;
    private int[,] P;
private int[,] PCut;
private int lbs, lbe, rbs, rbe, b1s, b1e, b2s, b2e, nBlock;
private void btnLoadImage_Click() { InitializeImage(); GetPaperBoundary(out lbs, out lbe, out rbs, out rbe);
gfxImg = Graphics.FromImage(img);
//gfxImg.DrawRectangle(new Pen(new SolidBrush(Color.GreenYellow), 1), lbe, 0, (rbs - lbe), img.Height); GetPaperStain(lbe, rbs);
} private void InitializeImage() {
String fileNameUrl="";
img = new Bitmap(fileNameUrl);

filename = fileNameUrl;
pbxImage.Height = img.Height;
pbxImage.Width = img.Width;
pbxImage.Image = img;
R = new int[img.Height, img.Width];
G = new int[img.Height, img.Width];
B = new int[img.Height, img.Width];
RRaw = new int[img.Height, img.Width];
GRaw = new int[img.Height, img.Width];
BRaw = new int[img.Height, img.Width];
for (int i = 0; i < img.Height; i++) 
for (int j = 0; j < img.Width; j++) {
Color c = img.GetPixel(j, i);
R[i, j] = (c.R > R_THRESHOLD ? 0 : 1);
G[i, j] = (c.G > G_THRESHOLD ? 0 : 1);
B[i, j] = (c.B > B_THRESHOLD ? 0 : 1);
RRaw[i, j] = c.R;
GRaw[i, j] = c.G;
BRaw[i, j] = c.B;
} }
private void GetPaperBoundary(
out int leftBoundStart, out int leftBoundEnd,
out int rightBoundStart, out int rightBoundEnd)
{
leftBoundStart = 0;
leftBoundEnd = 0;
rightBoundStart = 0;
rightBoundEnd = 0;
int[] seg = new int[img.Width];
for (int i = 0; i < img.Width; i++) 
seg[i] = (Enumerable.Range(0, img.Height).Average(y => B[y, i]) > 0.9 ? 1 : 0);
bool flag = false;
for (int i = 1; i < img.Width - 1; i++) {
if (seg[i] == 1 && seg[i + 1] == 1) flag = true;
if (flag && seg[i] == 1 && seg[i - 1] == 0) leftBoundStart = i;
if (flag && seg[i] == 0) {
leftBoundEnd = i - 1;
break;
}
}
leftBoundStart -= 5;
leftBoundEnd += 5; flag = false;
for (int i = leftBoundEnd + 1; i < img.Width - 1; i++) {
if (seg[i] == 1 && seg[i + 1] == 1) flag = true;
if (flag && seg[i] == 1 && seg[i - 1] == 0) rightBoundStart = i;
if (flag && seg[i] == 0) {
rightBoundEnd = i - 1;
break;
}
}
rightBoundStart -= 5;
rightBoundEnd += 5; }
private void GetPaperStain(int lbe, int rbs) {

PCut = new int[pHeight, pWidth];
    P = new int[img.Height, pWidth];
for (int i = 0; i < pHeight; i++)
for (int j = 0; j < pWidth; j++)
PCut[i, j] = GRaw[50 + i, lbe + pWidth + j];    for (int i = 0; i < img.Height; i++)
        for (int j = 0; j < pWidth; j++)
            P[i, j] = GRaw[i, lbe + pWidth + j]; /*
Bitmap blue = new Bitmap(640, 480);
for (int i = 0; i < 320; i++)
for (int j = 0; j < 40; j++)
blue.SetPixel(j, i, Color.FromArgb(255, P[i,j], P[i,j], P[i,j]));
pbxImage.Image = blue;
*/ b1s = 0;
b1e = 0;
b2s = 0;
b2e = 0;
int[] paperY = new int[pHeight];
for (int i = 0; i < pHeight; i++)
paperY[i] = Enumerable.Range(0, pWidth).Sum(x => PCut[i, x]); double c = 0.6 * paperY.Sum()/paperY.Length + 0.4 * paperY.Min(); 
int[] index = Enumerable.Range(0, pHeight).Where(h => paperY[h] < c).ToArray(); nBlock = 1;
bool flag = true;
for (int i = 0; i < index.Length - 1; i++) {
if (index[i + 1] > index[i] + 3) {
nBlock++;
b1e = index[i];
b2s = index[i + 1];
break;
}
}
int up, down;
b1s = index.First();
if (nBlock == 1) {
b1e = index.Last();
Step2(Math.Max(0, b1s - 30 + 50), Math.Min(pHeight, b1e + 30 +50), out b1s, out b1e);
gfxImg.DrawRectangle(new Pen(new SolidBrush(Color.Blue), 1), lbe, b1s , (rbs - lbe), b1e - b1s);        int sum = 0;
        for (int i = b1s; i < b1e; i++)
            for (int j = lbe; j < rbs; j++)
                sum += GRaw[i, j];
        sum /= (b1e - b1s) * (rbs - lbe);
        label1.Text = "色块1平均灰度值:" + sum; }
else if (nBlock == 2) {
b2e = index.Last();
Step2(Math.Max(0, b1s - 30 + 50), Math.Min(img.Height, b1e + 30 + 50), out b1s, out b1e);
gfxImg.DrawRectangle(new Pen(new SolidBrush(Color.Blue), 1), lbe, b1s , (rbs - lbe), b1e - b1s);
        int sum = 0;
        for (int i = b1s; i < b1e; i++)
            for (int j = lbe; j < rbs; j++)
                sum += GRaw[i, j];
        sum /= (b1e - b1s) * (rbs - lbe);
        label1.Text = "色块1平均灰度值:" + sum; Step2(Math.Max(0, b2s - 30 + 50), Math.Min(img.Height, b2e + 30 +50), out b2s, out b2e);
gfxImg.DrawRectangle(new Pen(new SolidBrush(Color.Blue), 1), lbe, b2s , (rbs - lbe), b2e - b2s);
        sum = 0;
        for (int i = b2s; i < b2e; i++)
            for (int j = lbe; j < rbs; j++)
                sum += GRaw[i, j];
        sum /= (b2e - b2s) * (rbs - lbe);
        label2.Text = "色块2平均灰度值:" + sum;
}
}private void Step2(int s, int e, out int up, out int down) {
int min = 255;
for (int i = s; i < e + 1; i++) 
for (int j = 0; j < pWidth; j++)
min = Math.Min(min, P[i, j]); if (min < 130)
GetStain1(s, e, out up, out down);
else GetStain2(s, e, out up, out down);
}private void GetStain1(int s, int e, out int up, out int down) {
double[] avgY = new double[img.Height];
    for (int i = 0; i < img.Height; i++)
avgY[i] = Enumerable.Range(0, pWidth).Sum(x => P[i, x]);    double[] difY = new double[img.Height];
    for (int i = 0; i < img.Height - 1; i++) 
difY[i] = avgY[i + 1] - avgY[i]; double avgDifY = difY.Skip(s).Take(e - s + 1).Average();
double sdY = Math.Sqrt(difY.Skip(s).Take(e - s + 1).Sum(x => (x - avgDifY) * (x - avgDifY)) / (e - s)); up = Enumerable.Range(s, e - s + 1).Where(x => difY[x] < -0.6 * sdY).Min();
down = Enumerable.Range(s, e - s + 1).Where(x => difY[x] > 0.6 * sdY).Max();
}private void GetStain2(int s, int e, out int up, out int down) {
    double[] avgY = new double[img.Height];
    for (int i = 0; i < img.Height; i++)
avgY[i] = Enumerable.Range(0, pWidth).Sum(x => P[i, x]);    double[] difY = new double[img.Height];
    for (int i = 0; i < img.Height - 1; i++)
difY[i] = avgY[i + 1] - avgY[i]; up = Enumerable.Range(s, e - s + 1).First(x => difY[x] == difY.Skip(s).Take(e - s + 1).Min());
down = Enumerable.Range(s, e - s + 1).First(x => difY[x] == difY.Skip(s).Take(e - s + 1).Max());
}}
private void btnExport_Click() {
pbxImage.Image.Save(filename + ".ed.bmp");
//Bitmap test = new Bitmap(rbs - lbe, b1e - b1s);
StreamWriter swR = new StreamWriter(filename + ".Block1.R.csv");
StreamWriter swG = new StreamWriter(filename + ".Block1.G.csv");
StreamWriter swB = new StreamWriter(filename + ".Block1.B.csv");
for (int i = b1s; i < b1e; i++) {
for (int j = lbe; j < rbs; j++) {
swR.Write(RRaw[i, j] + ", ");
swG.Write(GRaw[i, j] + ", ");
swB.Write(BRaw[i, j] + ", ");
//test.SetPixel(j - lbe, i - b1s, Color.FromArgb(255, RRaw[i, j], GRaw[i, j], BRaw[i, j]));
}
swR.WriteLine();
swG.WriteLine();
swB.WriteLine();
}
swR.Close();
swG.Close();
swB.Close();
//test.Save("test.bmp");
if (nBlock == 2) {
swR = new StreamWriter(filename + ".Block2.R.csv");
swG = new StreamWriter(filename + ".Block2.G.csv");
swB = new StreamWriter(filename + ".Block2.B.csv");
for (int i = b2s; i < b2e; i++) {
for (int j = lbe; j < rbs; j++) {
swR.Write(RRaw[i, j] + ", ");
swG.Write(GRaw[i, j] + ", ");
swB.Write(BRaw[i, j] + ", ");
}
swR.WriteLine();
swG.WriteLine();
swB.WriteLine();
}
swR.Close();
swG.Close();
swB.Close();
} Bitmap bmpDif = new Bitmap(320, 512);
Graphics gfxDif = Graphics.FromImage(bmpDif); double[] avgY = new double[img.Height];
for (int i = 0; i < img.Height; i++)
avgY[i] = Enumerable.Range(0, pWidth).Sum(x => P[i, x]); double[] difY = new double[img.Height];
for (int i = 0; i < img.Height - 1; i++)
difY[i] = avgY[i + 1] - avgY[i]; int prevX = 0, prevY = 256;
for (int i = 1; i < img.Height; i++) {
int currX = i;
int currY = 256 - (int)difY[i];
gfxDif.DrawLine(new Pen(Color.Blue), prevX, prevY, currX, currY);
prevX = currX;
prevY = currY;
}
bmpDif.Save(filename + ".difCurve.bmp");}}上面是C#代码,控件部分可以注释掉