lab 正交空间颜色校正
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesRaster;
namespace MapControlApplication1
{
public partial class lab : Form
{
public lab()
{
}
InitializeComponent();
private void Read_ref_image_Click(object sender, EventArgs e)
{
openFileDialog1.FileName = "";
openFileDialog1.Multiselect = false;
openFileDialog1.ShowDialog(this);
if (openFileDialog1.FileName != "")
{
Ref_layerlist.Items.Clear();
string[] strFileNames = openFileDialog1.FileNames;
foreach (string strFileName in strFileNames)
Ref_layerlist.Items.Add(strFileName);
//将文件在 list 中列表
{
}
}
}
private void Del_ref_image_Click(object sender, EventArgs e)
{
}
Ref_layerlist.Items.Clear();
private void Cancel_Click(object sender, EventArgs e)
{
}
this.Close();
this.Dispose();
private void Read_calibrate_image_Click(object sender, EventArgs e)
{
openFileDialog1.FileName = "";
openFileDialog1.Multiselect = true;
openFileDialog1.ShowDialog(this);
if (openFileDialog1.FileName != "")
{
Calibrate_layerlist.Items.Clear();
string[] strFileNames = openFileDialog1.FileNames;
foreach (string strFileName in strFileNames)
Calibrate_layerlist.Items.Add(strFileName);
//将文件在 list 中列表
{
}
}
}
private void Del_calibrate_image_Click(object sender, EventArgs e)
{
}
Calibrate_layerlist.Items.Clear();
private void Color_calibrate_Click(object sender, EventArgs e)
{ //lab 变换结果本应该保存,但数据太大,不能开辟内存
progressBar1.Visible = true; progressBar1.Value = 1; label1.Visible = false;
if (Calibrate_layerlist.Items.Count == 0 || Ref_layerlist.Items.Count == 0)
{
}
MessageBox.Show("没有输入参考图像或校正图像!");
return;
double[,] Ref_LabMean ={ { 0 }, { 0 }, { 0 } };//参考图像像元值均值
double[,] Ref_LabSD ={ { 0 }, { 0 }, { 0 } };//参考图像像元值均方差
double[,] ResultMatrix = Get_lab_result_matrix();//获得正交变换矩阵
double[,] rev_ResultMatrix = Get_revlab_result_matrix();//获得正交反变换矩阵
Get_lab_mean(Ref_layerlist.Items[0].ToString().Trim(), Ref_LabMean, ResultMatrix);//获取参考图像 lab 变换后均值
Get_lab_SD(Ref_layerlist.Items[0].ToString().Trim(), Ref_LabSD, Ref_LabMean, ResultMatrix);//获取参考图像 lab 变换后均方
差
double[,] Cal_LabMean = new double[3, 1];//校正图像像元值均值
double[,] Cal_LabSD = new double[3, 1];//校正图像像元值均方差
System.Array[] myWriteArrayRGB = new Array[3];//校正后待写入图像的数据
for (int i = 0; i < Calibrate_layerlist.Items.Count; i++)//对每个校正图进行校正
{
后均方差
Get_lab_mean(Calibrate_layerlist.Items[i].ToString().Trim(), Cal_LabMean, ResultMatrix);//获取校正图像 lab 变换后均值
Get_lab_SD(Calibrate_layerlist.Items[i].ToString().Trim(), Cal_LabSD, Cal_LabMean, ResultMatrix);//获取校正图像 lab 变换
Lab_Calibrate(i, Calibrate_layerlist.Items[i].ToString().Trim(), ResultMatrix, rev_ResultMatrix, Ref_LabMean, Ref_LabSD,
Cal_LabMean, Cal_LabSD);//校正一个图像
}
label1.Visible = true; label1.Text = "执行完毕!";
}
private void Get_lab_SD(string FullFileName, double[,] LabSD, double[,] LabMean, double[,] ResultMatrix)
{
double[,] RGBPixel ={ { 0 }, { 0 }, { 0 } };
double[,] LABPixel ={ { 0 }, { 0 }, { 0 } };
double[,] LabNum ={ { 0 }, { 0 }, { 0 } };
LabSD[0, 0] = LabSD[1, 0] = LabSD[2, 0] = 0;
int i, j, k, n = 0;
int PixelBlockHeight, PixelBlockWidth;
IRasterDataset myRasterDataset = new RasterDatasetClass();
myRasterDataset.OpenFromFile(FullFileName);//由文件名建立一个 rasterdataset
IRasterBandCollection myRasterBandCollection = myRasterDataset as IRasterBandCollection;
long BandCount = myRasterBandCollection.Count;
IRaster myRaster = myRasterDataset.CreateDefaultRaster() as IRaster;
IRasterCursor myRasterCursor = myRaster.CreateCursor();//图像分块计算
IPixelBlock3 myPixelBlock = null;
do
{
myPixelBlock = myRasterCursor.PixelBlock as IPixelBlock3;
PixelBlockHeight = myPixelBlock.Height;
PixelBlockWidth = myPixelBlock.Width;
for (i = 0; i < PixelBlockWidth; i++)
{
for (j = 0; j < PixelBlockHeight; j++)
{
if (double.Parse(myPixelBlock.GetVal(0, i, j).ToString()) != 0 && double.Parse(myPixelBlock.GetVal(1, i,
j).ToString()) != 0 && double.Parse(myPixelBlock.GetVal(2, i, j).ToString()) != 0)//零值不做统计
{//非零值才计算
for (k = 0; k < 3; k++)
{
}
RGBPixel[k, 0] = double.Parse(myPixelBlock.GetVal(k, i, j).ToString());//提取 RGB 三元素
LABPixel = Multiply_result_matrix(ResultMatrix, RGBPixel);//lab 正交变换结果
for (k = 0; k < 3; k++)
LabSD[k, 0] = LabSD[k, 0] + Math.Pow(Math.Pow(LABPixel[k, 0] - LabMean[k, 0], 2), 0.5);//求各个层的像元值
LabNum[k, 0]++;//求各层非零像元值个数;
方差总和
{
}
}
}
}
progressBar1.Value = n++; if (n > 100) n = 0;
} while (myRasterCursor.Next());
for (k = 0; k < 3; k++)
LabSD[k, 0] = LabSD[k, 0] / LabNum[k, 0];//各个图层的均方差
{
}
}
private void Get_lab_mean(string FullFileName, double[,] LabMean, double[,] ResultMatrix)
{
double[,] LabSum ={ { 0 }, { 0 }, { 0 } };//像元值的总和,用于求均值
double[,] LabNum ={ { 0 }, { 0 }, { 0 } };//像元值的个数,用于求均值
double[,] RGBPixel ={ { 0 }, { 0 }, { 0 } };
double[,] LABPixel ={ { 0 }, { 0 }, { 0 } };
LabMean[0, 0] = LabMean[1, 0] = LabMean[2, 0] = 0;
int i, j, k, n = 0;
//lab 变换结果本应该保存,但数据太大,不能开辟内存
int PixelBlockHeight, PixelBlockWidth;
IRasterDataset myRasterDataset = new RasterDatasetClass();
myRasterDataset.OpenFromFile(FullFileName);//由文件名建立一个 rasterdataset
IRasterBandCollection myRasterBandCollection = myRasterDataset as IRasterBandCollection;
long BandCount = myRasterBandCollection.Count;
IRaster myRaster = myRasterDataset.CreateDefaultRaster() as IRaster;
IRasterCursor myRasterCursor = myRaster.CreateCursor();
IPixelBlock3 myPixelBlock = null;
do
{
myPixelBlock = myRasterCursor.PixelBlock as IPixelBlock3;
PixelBlockHeight = myPixelBlock.Height;
PixelBlockWidth = myPixelBlock.Width;
for (i = 0; i < PixelBlockWidth; i++)
{
for (j = 0; j < PixelBlockHeight; j++)
{
if (double.Parse(myPixelBlock.GetVal(0, i, j).ToString()) != 0 && double.Parse(myPixelBlock.GetVal(1, i,
j).ToString()) != 0 && double.Parse(myPixelBlock.GetVal(2, i, j).ToString()) != 0)//零值不做统计
{//非零值才计算
for (k = 0; k < 3; k++)
{
}
RGBPixel[k, 0] = double.Parse(myPixelBlock.GetVal(k, i, j).ToString());//提取 RGB 三元素
LABPixel = Multiply_result_matrix(ResultMatrix, RGBPixel);//lab 正交变换结果
for (k = 0; k < 3; k++)
{
LabSum[k, 0] = LabSum[k, 0] + LABPixel[k, 0];//求各个层的像元值总和
LabNum[k, 0]++;//求各层非零像元值个数;
}
}
}
}
progressBar1.Value = n++; if (n > 100) n = 0;
} while (myRasterCursor.Next());
for (i = 0; i < 3; i++)
LabMean[i, 0] = LabSum[i, 0] / LabNum[i, 0];
{
}
}
private void Lab_Calibrate(int ImageCount, string FullFileName, double[,] ResultMatrix, double[,] rev_ResultMatrix,
double[,] Ref_LabMean, double[,] Ref_LabSD, double[,] Cal_LabMean, double[,] Cal_LabSD)
{
int k, n = 0;
IRasterDataset myRasterDataset = new RasterDatasetClass();
myRasterDataset.OpenFromFile(FullFileName);//由文件名建立一个 rasterdataset
IRasterBandCollection myRasterBandCollection = myRasterDataset as IRasterBandCollection;
long BandCount = myRasterBandCollection.Count;
IRaster myRaster = myRasterDataset.CreateDefaultRaster() as IRaster;
IRasterCursor myRasterCursor = myRaster.CreateCursor();//待处理图像的 RasterCursor
IPixelBlock3 myPixelBlock = null;
int speraIdx = FullFileName.LastIndexOf("\\");
string Pathname = FullFileName.Substring(0, speraIdx);
string ByFilename = FullFileName.Substring(speraIdx + 1);
string WriteFilename = ByFilename.Substring(0, ByFilename.Length - 4) + "_calibrate" + ".tif";
IWorkspaceFactory WorkspaceFactory = new RasterWorkspaceFactoryClass();//创建一个和输入图像相同的写入图像
IRasterWorkspace2 myRasterWorkspace = WorkspaceFactory.OpenFromFile(Pathname, 0) as IRasterWorkspace2;
IRasterDataset myWriteRasterDataset = CreateRasterbyFile(Pathname, "WriteTempRaster" + ImageCount.ToString() + ".tif",
ByFilename);
IRaster myWriteRaster = myWriteRasterDataset.CreateDefaultRaster();
IRasterProps myWriteRasterProps = myWriteRaster as IRasterProps;
IRasterCursor myWriteRasterCursor = myWriteRaster.CreateCursor();//写图像的 RasterCursor
IPnt myPnt = new PntClass();
IPixelBlock3 myWritePixelBlock = null;
int PixelBlockHeight, PixelBlockWidth;
System.Array[] myWriteArrayRGB = new Array[3];
IRasterEdit myRasterEdit = null;
do
{
myPixelBlock = myRasterCursor.PixelBlock as IPixelBlock3;
myWritePixelBlock = myWriteRasterCursor.PixelBlock as IPixelBlock3;
PixelBlockHeight = myPixelBlock.Height;
PixelBlockWidth = myPixelBlock.Width;
for (k = 0; k < 3; k++)
{
}
myWriteArrayRGB[k] = myWritePixelBlock.get_PixelData(k) as System.Array;//创建写字符串
Calibrate(myPixelBlock, myWriteArrayRGB, ResultMatrix, rev_ResultMatrix, Ref_LabMean, Ref_LabSD, Cal_LabMean,
Cal_LabSD);
for (k = 0; k < 3; k++)
{
}
myWritePixelBlock.set_PixelData(k, myWriteArrayRGB[k]);//将数据写入 pixelblock
myRasterEdit = myWriteRaster as IRasterEdit;
myPnt = myWriteRasterCursor.TopLeft;//写入数据的起始位置
myRasterEdit.Write(myPnt, myWritePixelBlock as IPixelBlock);
//将像元数据块中数据写入图像中
myRasterEdit.Refresh();
progressBar1.Value = n++; if (n > 100) n = 0;
} while (myRasterCursor.Next() && myWriteRasterCursor.Next());
myWriteRasterProps.NoDataValue = 0;//将图像 NoData 值设定为 0 值
if (File.Exists(Pathname +"\\"+ WriteFilename))
{
}
IDataset myDataset = RasterWorkspace2.OpenRasterDataset(WriteFilename) as IDataset;
myDataset.Delete();
ISaveAs mySaveAs = myWriteRaster as ISaveAs;
mySaveAs.SaveAs(WriteFilename, myRasterWorkspace as IWorkspace, "TIFF");
}
private void Calibrate(IPixelBlock3 myPixelBlock, System.Array[] myWriteArrayRGB, double[,] ResultMatrix, double[,]
rev_ResultMatrix, double[,] Ref_LabMean, double[,] Ref_LabSD, double[,] Cal_LabMean, double[,] Cal_LabSD)
{
double[,] RGBPixel ={ { 0 }, { 0 }, { 0 } };
double[,] LABPixel ={ { 0 }, { 0 }, { 0 } };
double[,] cal_LABPixel ={ { 0 }, { 0 }, { 0 } };
double[,] cal_RGBPixel ={ { 0 }, { 0 }, { 0 } };
int RasterHeight = myPixelBlock.Height;
int RasterWidth = myPixelBlock.Width;
int i, j, k;
for (i = 0; i < RasterWidth; i++)//对每个像元进行色彩校正
{
for (j = 0; j < RasterHeight; j++)
{
if (double.Parse(myPixelBlock.GetVal(0, i, j).ToString()) != 0 && double.Parse(myPixelBlock.GetVal(1, i, j).ToString()) !=
0 && double.Parse(myPixelBlock.GetVal(2, i, j).ToString()) != 0)//零值不做统计
{//非零值才计算
for (k = 0; k < 3; k++)
{
RGBPixel[k, 0] = double.Parse(myPixelBlock.GetVal(k, i, j).ToString());//提取 RGB 三元素
}
LABPixel = Multiply_result_matrix(ResultMatrix, RGBPixel);//每个像元 lab 正交变换结果
for (k = 0; k < 3; k++)
{//线性校正
cal_LABPixel[k, 0] = Ref_LabSD[k, 0] / Cal_LabSD[k, 0] * (LABPixel[k, 0] - Cal_LabMean[k, 0]) + Ref_LabMean[k,
0];
}
cal_RGBPixel = Multiply_result_matrix(rev_ResultMatrix, cal_LABPixel);//每个像元反 lab 正交变换结果
for (k = 0; k < 3; k++)
//if (cal_RGBPixel[k, 0] > 255) cal_RGBPixel[k, 0] = 255;
//if (cal_RGBPixel[k, 0] < 0) cal_RGBPixel[k, 0] = 0;
myWriteArrayRGB[k].SetValue(Convert.ToInt16(cal_RGBPixel[k, 0]), i, j);//将结果写入字符串并等待写入文件
{
}
}
}
progressBar1.Value = i * 100 / RasterWidth;
}
}
private IRasterDataset CreateRasterbyFile(string Pathname, string NewFilename, string ByFilename)
{
IWorkspaceFactory WorkspaceFactory = new RasterWorkspaceFactoryClass();
IRasterWorkspace2 RasterWorkspace2 = WorkspaceFactory.OpenFromFile(Pathname, 0) as IRasterWorkspace2;
IRasterDataset RasterDataset = RasterWorkspace2.OpenRasterDataset(ByFilename);
IRaster Raster = RasterDataset.CreateDefaultRaster();
IRasterProps RasterProps = Raster as IRasterProps;
IRasterBandCollection myRasterBandCollection = Raster as IRasterBandCollection;
int numBands = myRasterBandCollection.Count;
IPnt Pnt = RasterProps.MeanCellSize();
if (File.Exists(Pathname +"\\"+ NewFilename))
{
}
IDataset myDataset = RasterWorkspace2.OpenRasterDataset(NewFilename) as IDataset;
myDataset.Delete();
return RasterWorkspace2.CreateRasterDataset(NewFilename, "TIFF", RasterProps.Extent.LowerLeft, RasterProps.Width,
RasterProps.Height, Pnt.X, Pnt.Y, numBands, rstPixelType.PT_SHORT, RasterProps.SpatialReference, true);
}
private double[,] Get_lab_result_matrix()
{
double[,] Matrix1 ={ { 0.57735, 0, 0 }, { 0, 0.40825, 0 }, { 0, 0, 0.70711 } };
double[,] Matrix2 ={ { 1, 1, 1 }, { 1, 1, -2 }, { 1, -1, 0 } };
double[,] Matrix3 ={ { 0.3811, 0.5783, 0.0402 }, { 0.1967, 0.7244, 0.0782 }, { 0.0241, 0.1288, 0.8444 } };
double[,] ResultMatrix = Multiply_result_matrix(Matrix1, Matrix2);
ResultMatrix = Multiply_result_matrix(ResultMatrix, Matrix3);//变换矩阵结果
return ResultMatrix;
}
private double[,] Get_revlab_result_matrix()
{
}
double[,] Matrix1 ={ { 4.4679, -3.5873, 0.1193 }, { -1.2186, 2.3809, -0.1624 }, { 0.0497, -0.2439, 1.2045 } };
double[,] Matrix2 ={ { 1, 1, 1 }, { 1, 1, -1 }, { 1, -2, 0 } };
double[,] Matrix3 ={ { 0.57735, 0, 0 }, { 0, 0.40825, 0 }, { 0, 0, 0.70711 } };
double[,] ResultMatrix = Multiply_result_matrix(Matrix1, Matrix2);
ResultMatrix = Multiply_result_matrix(ResultMatrix, Matrix3);//变换矩阵结果
return ResultMatrix;
private double[,] Multiply_result_matrix(double[,] matrix1, double[,] matrix2)
{
int row1 = matrix1.GetLength(0);
int col1 = matrix1.Length / matrix1.GetLength(0);
int row2 = matrix2.GetLength(0);
int col2 = matrix2.Length / matrix2.GetLength(0);
if (col1 != row2)
{
}
MessageBox.Show("矩阵大小不匹配,不能做矩阵乘法!");
return null;
double[,] ResultMatrix = new double[row1, col2];
int i, j, k;
for (i = 0; i < row1; i++)//结果矩阵行数
{
}
for (j = 0; j < col2; j++)//结果矩阵列数
{
}
for (k = 0; k < col1; k++)//col1 与 row2 必须相等
{
}
ResultMatrix[i, j] = ResultMatrix[i, j] + matrix1[i, k] * matrix2[k, j];
return ResultMatrix;
}
}
}