From ec19ed39ae16897ce9ae2f192bb7418ed36aea47 Mon Sep 17 00:00:00 2001 From: qiupeng-linux Date: Fri, 10 Apr 2026 21:02:24 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=B5=8B=E8=AF=95=E8=BF=9E=E6=8E=A5?= =?UTF-8?q?=E6=B5=B7=E5=BA=B7=E6=91=84=E5=83=8F=E5=A4=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.cpp | 260 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 173 insertions(+), 87 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 3cd7886..abacea7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "MvCamera.h" @@ -73,6 +74,174 @@ static void PrintDeviceInfo(const MV_CC_DEVICE_INFO* pInfo, unsigned int index) std::cout << std::endl; } +static int ConfigureGamma(CMvCamera& camera, float gamma) +{ + // Some models expose GammaEnable; if unsupported, continue and try setting Gamma directly. + int nRet = camera.SetBoolValue("GammaEnable", true); + if (MV_OK != nRet) + { + std::cerr << "Warning: Set GammaEnable failed: " << ToHex(nRet) << std::endl; + } + + nRet = camera.SetFloatValue("Gamma", gamma); + if (MV_OK != nRet) + { + std::cerr << "Set Gamma failed: " << ToHex(nRet) << std::endl; + return nRet; + } + + std::cout << "Gamma configured: " << gamma << std::endl; + return MV_OK; +} + +static bool SaveFrameToBmp(CMvCamera& camera, const MV_FRAME_OUT& stFrame, const std::string& outFile) +{ + MV_SAVE_IMAGE_PARAM_EX3 stSaveParam; + std::memset(&stSaveParam, 0, sizeof(stSaveParam)); + + stSaveParam.enImageType = MV_Image_Bmp; + stSaveParam.enPixelType = stFrame.stFrameInfo.enPixelType; + stSaveParam.nWidth = stFrame.stFrameInfo.nWidth; + stSaveParam.nHeight = stFrame.stFrameInfo.nHeight; + stSaveParam.nDataLen = stFrame.stFrameInfo.nFrameLen; + stSaveParam.pData = stFrame.pBufAddr; + stSaveParam.iMethodValue = 0; + stSaveParam.nJpgQuality = 90; + + const unsigned int maxImageLen = + stFrame.stFrameInfo.nWidth * stFrame.stFrameInfo.nHeight * 4 + 2048; + std::vector imageBuffer(maxImageLen, 0); + + stSaveParam.pImageBuffer = imageBuffer.data(); + stSaveParam.nBufferSize = maxImageLen; + + int nRet = camera.SaveImage(&stSaveParam); + if (MV_OK != nRet) + { + std::cerr << "SaveImage failed: " << ToHex(nRet) << std::endl; + return false; + } + + FILE* fp = std::fopen(outFile.c_str(), "wb"); + if (fp == nullptr) + { + std::cerr << "Open output file failed: " << outFile << std::endl; + return false; + } + + const size_t writeBytes = std::fwrite(imageBuffer.data(), 1, stSaveParam.nImageLen, fp); + std::fclose(fp); + if (writeBytes != stSaveParam.nImageLen) + { + std::cerr << "Write output file failed: " << outFile << std::endl; + return false; + } + + std::cout << "Image saved: " << outFile + << ", bytes=" << stSaveParam.nImageLen << std::endl; + return true; +} + +[[maybe_unused]] static int CaptureOneFrameContinuousAndSave(CMvCamera& camera, const std::string& outFile) +{ + int nRet = camera.SetEnumValueByString("TriggerMode", "Off"); + if (MV_OK != nRet) + { + std::cerr << "Set TriggerMode Off failed: " << ToHex(nRet) << std::endl; + return nRet; + } + + nRet = camera.StartGrabbing(); + if (MV_OK != nRet) + { + std::cerr << "StartGrabbing failed: " << ToHex(nRet) << std::endl; + return nRet; + } + + // 连续模式通常会先等一会儿,让数据流稳定。 + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + + MV_FRAME_OUT stFrame = {}; + nRet = camera.GetImageBuffer(&stFrame, 3000); + if (MV_OK != nRet) + { + std::cerr << "GetImageBuffer failed: " << ToHex(nRet) << std::endl; + camera.StopGrabbing(); + return nRet; + } + + PrintFrameStructInfo(); + PrintRawBytes(&stFrame, sizeof(MV_FRAME_OUT), "stFrame"); + std::cout << "Grab success:" + << " width=" << stFrame.stFrameInfo.nWidth + << " height=" << stFrame.stFrameInfo.nHeight + << " frameLen=" << stFrame.stFrameInfo.nFrameLen + << " pixelType=0x" << std::hex << std::uppercase + << static_cast(stFrame.stFrameInfo.enPixelType) + << std::dec << std::endl; + + const bool saveOk = SaveFrameToBmp(camera, stFrame, outFile); + camera.FreeImageBuffer(&stFrame); + camera.StopGrabbing(); + return saveOk ? MV_OK : -1; +} + +static int CaptureOneFrameSoftwareTriggerAndSave(CMvCamera& camera, const std::string& outFile) +{ + int nRet = camera.SetEnumValueByString("TriggerMode", "On"); + if (MV_OK != nRet) + { + std::cerr << "Set TriggerMode On failed: " << ToHex(nRet) << std::endl; + return nRet; + } + + nRet = camera.SetEnumValueByString("TriggerSource", "Software"); + if (MV_OK != nRet) + { + std::cerr << "Set TriggerSource Software failed: " << ToHex(nRet) << std::endl; + return nRet; + } + + nRet = camera.StartGrabbing(); + if (MV_OK != nRet) + { + std::cerr << "StartGrabbing failed: " << ToHex(nRet) << std::endl; + return nRet; + } + + nRet = camera.CommandExecute("TriggerSoftware"); + if (MV_OK != nRet) + { + std::cerr << "TriggerSoftware failed: " << ToHex(nRet) << std::endl; + camera.StopGrabbing(); + return nRet; + } + + MV_FRAME_OUT stFrame = {}; + nRet = camera.GetImageBuffer(&stFrame, 3000); + if (MV_OK != nRet) + { + std::cerr << "GetImageBuffer failed: " << ToHex(nRet) << std::endl; + camera.StopGrabbing(); + return nRet; + } + + PrintFrameStructInfo(); + PrintRawBytes(&stFrame, sizeof(MV_FRAME_OUT), "stFrame"); + std::cout << "Grab success:" + << " width=" << stFrame.stFrameInfo.nWidth + << " height=" << stFrame.stFrameInfo.nHeight + << " frameLen=" << stFrame.stFrameInfo.nFrameLen + << " pixelType=0x" << std::hex << std::uppercase + << static_cast(stFrame.stFrameInfo.enPixelType) + << std::dec << std::endl; + + const bool saveOk = SaveFrameToBmp(camera, stFrame, outFile); + camera.FreeImageBuffer(&stFrame); + camera.StopGrabbing(); + return saveOk ? MV_OK : -1; +} + int main() { @@ -140,107 +309,24 @@ int main() } } - // 连续采集模式 - nRet = camera.SetEnumValueByString("TriggerMode", "Off"); + nRet = ConfigureGamma(camera, 0.6f); if (MV_OK != nRet) { - std::cerr << "Set TriggerMode Off failed: " << ToHex(nRet) << std::endl; - camera.Close(); - CMvCamera::FinalizeSDK(); - return 1; - } - - nRet = camera.StartGrabbing(); - if (MV_OK != nRet) - { - std::cerr << "StartGrabbing failed: " << ToHex(nRet) << std::endl; - camera.Close(); - CMvCamera::FinalizeSDK(); - return 1; - } - - // 稍等一会儿,让流稳定一点 - std::this_thread::sleep_for(std::chrono::milliseconds(200)); - - MV_FRAME_OUT stFrame = {}; - nRet = camera.GetImageBuffer(&stFrame, 3000); - if (MV_OK != nRet) - { - std::cerr << "GetImageBuffer failed: " << ToHex(nRet) << std::endl; - camera.StopGrabbing(); - camera.Close(); - CMvCamera::FinalizeSDK(); - return 1; - } - - PrintFrameStructInfo(); - PrintRawBytes(&stFrame, sizeof(MV_FRAME_OUT), "stFrame"); - - std::cout << "Grab success:" - << " width=" << stFrame.stFrameInfo.nWidth - << " height=" << stFrame.stFrameInfo.nHeight - << " frameLen=" << stFrame.stFrameInfo.nFrameLen - << " pixelType=0x" << std::hex << std::uppercase - << static_cast(stFrame.stFrameInfo.enPixelType) - << std::dec << std::endl; - - // 保存为 bmp/jpg 都可以 - MV_SAVE_IMAGE_PARAM_EX3 stSaveParam; - std::memset(&stSaveParam, 0, sizeof(stSaveParam)); - - stSaveParam.enImageType = MV_Image_Bmp; // 也可改为 MV_Image_Jpeg - stSaveParam.enPixelType = stFrame.stFrameInfo.enPixelType; - stSaveParam.nWidth = stFrame.stFrameInfo.nWidth; - stSaveParam.nHeight = stFrame.stFrameInfo.nHeight; - stSaveParam.nDataLen = stFrame.stFrameInfo.nFrameLen; - stSaveParam.pData = stFrame.pBufAddr; - stSaveParam.iMethodValue = 0; - stSaveParam.nJpgQuality = 90; - - const unsigned int maxImageLen = - stFrame.stFrameInfo.nWidth * stFrame.stFrameInfo.nHeight * 4 + 2048; - - unsigned char* pImageBuffer = new unsigned char[maxImageLen]; - std::memset(pImageBuffer, 0, maxImageLen); - - stSaveParam.pImageBuffer = pImageBuffer; - stSaveParam.nBufferSize = maxImageLen; - - nRet = camera.SaveImage(&stSaveParam); - if (MV_OK != nRet) - { - std::cerr << "SaveImage failed: " << ToHex(nRet) << std::endl; - delete[] pImageBuffer; - camera.FreeImageBuffer(&stFrame); - camera.StopGrabbing(); camera.Close(); CMvCamera::FinalizeSDK(); return 1; } + // 保留连续采集路径,同时 main 默认走软件触发单帧采集。 const std::string outFile = "grab_result.bmp"; - FILE* fp = std::fopen(outFile.c_str(), "wb"); - if (fp == nullptr) + nRet = CaptureOneFrameSoftwareTriggerAndSave(camera, outFile); + if (MV_OK != nRet) { - std::cerr << "Open output file failed: " << outFile << std::endl; - delete[] pImageBuffer; - camera.FreeImageBuffer(&stFrame); - camera.StopGrabbing(); camera.Close(); CMvCamera::FinalizeSDK(); return 1; } - std::fwrite(pImageBuffer, 1, stSaveParam.nImageLen, fp); - std::fclose(fp); - - std::cout << "Image saved: " << outFile - << ", bytes=" << stSaveParam.nImageLen << std::endl; - - delete[] pImageBuffer; - - camera.FreeImageBuffer(&stFrame); - camera.StopGrabbing(); camera.Close(); CMvCamera::FinalizeSDK();