转载于:https://blog.csdn.net/y459541195 软件解决CCD线阵相机彩色图像校正方法 一、主要方法步骤 1.相机上电,打开光源 2.光圈为2 3.行频为工况行频 4.增益ALL为1,绿色为1。 5.使用白色漫反射板 6.图像格式为RGB8,图像大小设为为4096100 7.调整曝光时间,使图片绿色通道不过曝,且平均值在200左右,记录此时的曝光时间,用于工况。 8.分别调整红蓝增益,使红色和蓝色像素的均值与绿色通道基本一致,记录此时的红蓝增益,用于工况。 9.保存图像,文件名为001.BMP 10.调整增益ALL为工况下的增益。 11.在程序中使用001.BMP 12.001.BMP拆成RGB三通道 13.以绿色通道为例,对BMP的每一列(高度方向)求均值,取整。得到40961的数据 14.对这个数据再求MAX值,然后再转化为最大值为255的行,数据为40961。 15.实时采集得到一张图像,对G通道进行修正。 16.修正方法为每个像素的G值255/对应列的修正值,不超过255。 17.红蓝通道参考绿色通道进行调整。 18.将所计算后的校正系数存起来,采集彩色图像处理计算前,可先进行校正再处理。
代码如下:
`//
#include “stdafx.h” #include <opencv2/opencv.hpp> #include <highgui/highgui.hpp> #include #include<math.h> #include #include #include <opencv2\imgproc\types_c.h> #include <ctype.h> #include<windows.h> #include #include
using namespace std; using namespace cv;
Mat src,img,srcresize,imgresize,dst; String input_path = “E:\…\work\001.bmp”;//标定过的图 String input_path_src = “E:\…\work\*.bmp”;//待修正图
const char* src_dst = “原图修正后”; const char* src_input = “原图”;
int _tmain(int argc, _TCHAR* argv[]) {
img = imread(input_path);
src = imread(input_path_src);
if (!src.data)
{
printf("could not load image ... \n");
return -1;
}
dst.create(src.size(), src.type());
/**********************通道求均值***************************/
vector<int> pImgVector;
//对标定图像列求均值
for (int col = 0; col < img.cols;col++)
{
Mat colRange = img.colRange(col, col + 1);
Scalar meanImg = mean(colRange);
//cout << "meanImg:" << meanImg << endl;
double dImg = (meanImg[0] + meanImg[1] + meanImg[2]) / 3;
//cout << "dImg:" << dImg << endl;
pImgVector.push_back(dImg);
}
vector<int>::iterator biggestImg = max_element(begin(pImgVector), end(pImgVector));
//cout << "pImgVector最大值:" << *biggestImg<<endl;
vector<double> pImgCoefficient;
for (int i = 0; i < pImgVector.size(); i++)
{
double pImgElement = (double)*biggestImg / (double)pImgVector[i];
std::cout << setiosflags(ios::fixed) << setprecision(2);//打印两位小数
//std::cout << "pBlueElement:" << pImgElement << endl;
pImgCoefficient.push_back(pImgElement);
}
//系数写入txt,提取系数可打开注释
/*ofstream fout;
fout.open("D:\\...\\coefficient.txt",ios_base::out);
if (fout.is_open())
{
for (vector<double>::iterator i = pImgCoefficient.begin(), end = pImgCoefficient.end(); i != end; ++i)
{
fout << (*i)<<",";
}
}
fout.close();*/
for (int row = 0; row < src.rows; row++)
{
for (int col = 0; col < src.cols; col++)
{
int b = src.at<Vec3b>(row, col)[0];
int g = src.at<Vec3b>(row, col)[1];
int r = src.at<Vec3b>(row, col)[2];
int dBlue = b*pImgCoefficient[col];
int dGreen = g*pImgCoefficient[col];
int dRed = r*pImgCoefficient[col];
/* if (dBlue > 255)
{
std::cout << "dBlue" << dBlue << endl;
dBlue = 255;
}
if (dGreen > 255)
{
std::cout << "dGreen" << dGreen << endl;
dGreen = 255;
}
if (dRed > 255)
{
std::cout << "dRed" << dRed << endl;
dRed = 255;
}*/
dst.at<Vec3b>(row, col)[0] = dBlue;
dst.at<Vec3b>(row, col)[1] = dGreen;
dst.at<Vec3b>(row, col)[2] = dRed;
}
}
namedWindow(src_input, WINDOW_AUTOSIZE);
namedWindow(src_dst, WINDOW_AUTOSIZE);
imshow(src_input, src);
imshow(src_dst, dst);`
结果:
|