我们使用EDSDK控制大炮Eos 7D,用于固定物体拍照。
我们尽量让一切都一样,包括相机位置、光圈、ISO、快门速度、对焦(手动对焦)、无闪光灯,一张一张的拍照,确保一切都没有改变。期望我们每次都能获得接近的RGB图像。
但后来我们发现每次拍摄的 JPG 图像都不一样。例如,我们计算整个物体块的RGB总和(块位置固定,背景纯暗——零),第一次得到RGB == (10000,20000,15000),第二次得到(12000, 24000,17000),第三次得到 (9000, 18000, 13000)。我们知道在拍摄照片时必须有一些小的方差/噪音。但是 RGB 值每次变化很大(-15% 到 15% 的差异),这一定不是噪音(我们猜测它一定是由一些自动调整设置引起的)。
为什么我们得到不同的结果?我们在哪里犯错?
我们也尝试获取原始格式图像(.CR2),然后使用 dcraw.exe 将其转换为 PPM 或 TIFF 格式,使用相同的转换参数(我们使用 -v -k 2400 -S 13000 -W -g 2.222 4.5)。但是图像 RGB 值每次仍然变化很大。
下面是我们的一些代码片段(在 C# 中,一些细节被忽略了)。
由于我们的任务是准确计算 RGB 值,所以这个问题对我们来说非常重要。非常感谢您的帮助 !
public void main(){
EDSDK.EdsInitializeSDK();
EDSDK.EdsGetCameraList(out cameraList);
EDSDK.EdsGetChildCount(cameraList, out cameraCount);
EDSDK.EdsGetChildAtIndex(cameraList, 0, out cam);
EDSDK.EdsGetDeviceInfo(cam, out deviceInfo);
EDSDK.EdsSetPropertyEventHandler(cam, EDSDK.PropertyEvent_All, propertyEventHandle, inContext);
ObjectEventHandle = new EDSDK.EdsObjectEventHandler(ObjectEventCallBack);
EDSDK.EdsSetObjectEventHandler(cam, EDSDK.ObjectEvent_All, ObjectEventHandle, IntPtr.Zero);
EDSDK.EdsSetCameraStateEventHandler(cam, EDSDK.StateEvent_All, stateEventHandle, inContext);
EDSDK.EdsOpenSession(cam);
EDSDK.EdsSetPropertyData(cam, EDSDK.PropID_SaveTo, 0, 4, (uint)EDSDK.EdsSaveTo.Host);
EDSDK.EdsSetPropertyData(cam, EDSDK.PropID_ImageQuality, 0, 4, (uint)0x0013ff0f);
EDSDK.EdsSetPropertyData(cam, EDSDK.PropID_Av, 0, 4, (uint)0x58);
EDSDK.EdsSetPropertyData(cam, EDSDK.PropID_Tv, 0, 4, (uint)0x6b);
EDSDK.EdsSetPropertyData(cam, EDSDK.PropID_ISOSpeed, 0, 4, (uint)0x48);
EDSDK.EdsCapacity capacity = default(EDSDK.EdsCapacity);
capacity.NumberOfFreeClusters = 0x10000000;
capacity.BytesPerSector = 0x0200;
capacity.Reset = 1;
EDSDK.EdsSetCapacity(cam, capacity);
EDSDK.EdsSendCommand(cam, EDSDK.CameraCommand_TakePicture, 0);
}
public void DownloadImage(String Path, IntPtr DirItem)
{
uint Err = 0;
EDSDK.EdsDirectoryItemInfo DirInfo;
Err = EDSDK.EdsGetDirectoryItemInfo(DirItem, out DirInfo);
if (Err != 0) throw new Exception();
IntPtr Stream;
Err = EDSDK.EdsCreateFileStream(Path, EDSDK.EdsFileCreateDisposition.CreateAlways, EDSDK.EdsAccess.ReadWrite, out Stream);
if (Err != 0) throw new Exception();
Err = EDSDK.EdsDownload(DirItem, DirInfo.Size, Stream);
if (Err != 0) throw new Exception();
Err = EDSDK.EdsDownloadComplete(DirItem);
if (Err != 0) throw new Exception();
Err = EDSDK.EdsRelease(Stream);
if (Err != 0) throw new Exception();
while (!System.IO.File.Exists(Path))
Thread.Sleep(100);
}
public uint ObjectEventCallBack(uint Event, IntPtr Object, IntPtr Context)
{
switch (Event)
{
case EDSDK.ObjectEvent_DirItemCreated:
foreach (EDSFileObject File in Results)
{
if (File.mFileInfo.isFolder == 0)
{
DownloadImage(Filepath, File.mFilePointer);
}
}
}
break;
}
return EDSDKLib.EDSDK.EDS_ERR_OK;
}