#include #include #include "S729.h" #include "S732.h" #include #include "opencv2/opencv.hpp" #include //#include //typedef unsigned char BYTE; //typedef unsigned int SINT32; using namespace std; using namespace cv; // 红外帧 unsigned short pFrameIR[IMAGE_WIDTH_IR*(IMAGE_HEIGHT_IR + PARA_IR_LINE)] = {0}; unsigned char pImageIR[IMAGE_WIDTH_IR*(IMAGE_HEIGHT_IR)] = {0}; unsigned short pFrameIR_732[S732_IR_W * (S732_IR_H + PARA_IR_LINE_S732)] = { 0 }; unsigned char pImageIR_732[S732_IR_W * (S732_IR_H)] = { 0 }; // 电视帧 unsigned char pFrameVL[IMAGE_WIDTH_VL * (IMAGE_HEIGHT_VL + PARA_IR_LINE) * 2] = { 0 }; unsigned char pImageVL[IMAGE_WIDTH_VL * (IMAGE_HEIGHT_VL) * 2] = { 0 }; unsigned short pFrameVL_732[S732_VL_W * (S732_VL_H + PARA_VL_LINE_S732)] = { 0 }; unsigned char pImageVL_732[S732_VL_W * (S732_VL_H)] = { 0 }; /* * 将Y16数据转换成Y8数据 */ void Map16BitTo8Bit_u(unsigned short* psh16BitData, int nDataLen, unsigned char* pby8BitData, int nBrightness, int nContrast, float lowP, float highP) { //int nBrightness = 100; //int nContrast = 100; if (pby8BitData == NULL || psh16BitData == NULL || nDataLen <= 0) { return; } //指向直方图的数据指针 int pHist[65536] = { 0 }; memset(pHist, 0, 65536 * sizeof(int)); int i = 0; for (i = 0; i < nDataLen; i++) { pHist[psh16BitData[i]]++; } //设置阈值大小为: AreaSigma*图象大小/100 int nSigmaLow = (int)(lowP * nDataLen); // 大动态范围 int nSigmaHigh = (int)(highP * nDataLen); // 大动态范围 int nSum = 0; int nMin = 0; int nMax = 0; //求映射的最大最小值 for (i = 0; i < 65536; i++) { nSum += pHist[i]; if (nSum >= nSigmaLow) { nMin = i; break; } } nSum = 0; for (i = 65535; i >= 0; i--) { nSum += pHist[i]; if (nSum >= nSigmaHigh) { nMax = i; break; } } nBrightness = (nBrightness > 100) ? 100 : nBrightness; nBrightness = (nBrightness < 0) ? 0 : nBrightness; nContrast = (nContrast > 100) ? 100 : nContrast; nContrast = (nContrast < 0) ? 0 : nContrast; //计算对比度亮度 float K = (float)(256.0 / (nMax - nMin + 1)) * float(2 * nContrast / 100.0); if (K > 1.0) { K = 1.0; } float C = (float)(128 * float(2 * nBrightness / 100.0) - K * (nMax + nMin) / 2); //图像映射 for (i = 0; i < nDataLen; i++) { int nValue = (int)(K * psh16BitData[i] + C); if (nValue < 0) { pby8BitData[i] = 0/*255*/; } else if (nValue > 255) { pby8BitData[i] = 255/*0*/; } else { pby8BitData[i] = nValue/*255 - nValue*/; } } } void Map16BitTo8Bit(unsigned short *psh16BitData, long lDataLen, BYTE *pby8BitData) { if (psh16BitData == NULL || pby8BitData == NULL || lDataLen <= 0) { return; } //指向直方图的数据指针 int *pHist = new int[65536]; memset(pHist, 0, 65536 * sizeof(int)); int i = 0; for(i = 0; i < lDataLen; i+=10) { pHist[psh16BitData[i]]++; } //设置阈值大小为: AreaSigma*图象大小/100 int nSigma = 0.02*lDataLen; int nSum = 0; int nMin = 0; int nMax = 0; //求映射的最大最小值 for(i = 0; i < 65536; i++) { nSum += pHist[i]; if(nSum >= nSigma) { nMin = i; break; } } nSum = 0; for(i = 65535; i >= 0; i--) { nSum += pHist[i]; if(nSum >= nSigma) { nMax = i; break; } } //计算对比度亮度 float K = (float)(120.0/(nMax - nMin + 1)); float C = (float)(-K * nMin); //图像映射 for (i = 0; i < lDataLen; i++) { int nValue = (int)(K * psh16BitData[i] + C); if (nValue < 0) { pby8BitData[i] = 0; } else if (nValue > 255) { pby8BitData[i] = 255; } else { pby8BitData[i] = nValue; } } delete[] pHist; } // 转换S729 raw到jpg和txt void convertS729_IR(string inputFile, string outputPath) { std::cout << "Converting S729...\n"; FILE* file = fopen(inputFile.c_str(), "rb"); if (!file) { std::cerr << "Error opening file: " << inputFile << std::endl; return; } // 打开txt文件用于存储文件名以及对应的参数 std::ofstream txtFile(outputPath + "list.txt"); int i = 0; while (!feof(file)) { fread(pFrameIR, 2, IMAGE_WIDTH_IR * (IMAGE_HEIGHT_IR + PARA_IR_LINE), file); S729paras_IR Paras_IR = { 0 }; memcpy(&Paras_IR, (unsigned char*)(pFrameIR + IMAGE_WIDTH_IR * IMAGE_HEIGHT_IR), sizeof(S729paras_IR)); Map16BitTo8Bit(pFrameIR, IMAGE_WIDTH_IR * IMAGE_HEIGHT_IR, pImageIR); cv::Mat mat_src(IMAGE_HEIGHT_IR, IMAGE_WIDTH_IR, CV_8UC1, pImageIR); // 保存jpg图像 std::string jpgFile = outputPath + "/" + "frame_" + std::to_string(i) + ".jpg"; cv::imwrite(jpgFile, mat_src); // 写入txt文件 txtFile << std::fixed << std::setprecision(6); txtFile << "Frame " << i << "," << Paras_IR.Paras_IR.airCraftInfo.B<< "," < parseDJISRT(const std::string& filename) { std::vector frames; std::ifstream file(filename); if (!file.is_open()) { std::cerr << "Error: Could not open file " << filename << std::endl; return frames; } std::string lines[5]; while (std::getline(file, lines[0])) { // Frame number line // Read next 4 lines for (int i = 1; i < 5; ++i) { if (!std::getline(file, lines[i])) break; } FrameData frame; // Line 1: Frame number frame.frameNumber = std::stoi(lines[0]); // Line 2: Time range (00:00:00,000 --> 00:00:00,033) frame.timeRange = lines[1]; // Line 3: FrameCnt and timestamp std::istringstream iss(lines[2]); std::string temp; iss >> temp >> frame.frameCnt >> frame.timestamp; // Line 4: Metadata (direct field extraction) const std::string& meta = lines[3]; frame.focal_len = extractValueAfter(meta, "focal_len: "); frame.dzoom_ratio = extractValueAfter(meta, "dzoom_ratio: "); frame.latitude = extractDoubleAfter(meta, "latitude: "); frame.longitude = extractDoubleAfter(meta, "longitude: "); frame.rel_alt = extractValueAfter(meta, "rel_alt: "); frame.abs_alt = extractValueAfter(meta, "abs_alt: "); frame.gb_yaw = extractValueAfter(meta, "gb_yaw: "); frame.gb_pitch = extractValueAfter(meta, "gb_pitch: "); frame.gb_roll = extractValueAfter(meta, "gb_roll: "); inferCameraParams_H30(frame, filename); frames.push_back(frame); // Skip the empty line (line 5) } file.close(); return frames; } void convertDJ(string videoPath, string outputPath) { cv::VideoCapture cap(videoPath); // Get video properties double fps = cap.get(cv::CAP_PROP_FPS); int width = static_cast(cap.get(cv::CAP_PROP_FRAME_WIDTH)); int height = static_cast(cap.get(cv::CAP_PROP_FRAME_HEIGHT)); int frame_count = static_cast(cap.get(cv::CAP_PROP_FRAME_COUNT)); // 解析srt文件 string srtPath = videoPath.substr(0, videoPath.find_last_of('.')) + ".srt"; std::vector srt = parseDJISRT(srtPath); printf("解析srt文件 done!\n"); // 打开txt文件用于存储文件名以及对应的参数 std::ofstream txtFile(outputPath + "/list.txt"); int frmID = 0; while (true) { printf("%d\n",frmID); cv::Mat mat; // Read a new frame cap >> mat; // Check if frame is empty (end of video) if (mat.empty()) { std::cout << "End of video\n"; cap.release(); break; } frmID++; if(frmID%25 !=0) { continue; } // 保存jpg图像 std::string jpgFile = outputPath + "/" + "frame_" + std::to_string(frmID) + ".jpg"; cv::imwrite(jpgFile, mat); // 写入txt文件 txtFile << std::fixed << std::setprecision(6); txtFile << "Frame " << frmID << "," << srt[frmID].latitude<< "," < " << std::endl; // return 1; //} string inputFilePath = "G:/202509baotou/20250928_155516413_28房子.yuv"; // 去除后缀,在同级目录建立output文件夹 string inputFileName = inputFilePath.substr(0, inputFilePath.find_last_of('.')); string outputPath = inputFileName + "_output"; // if (_mkdir(outputPath.c_str()) == -1) // { // std::cerr << "Error: Could not create output directory " << outputPath << std::endl; // return 1; // } //convertS729_VL(inputFilePath, outputPath); // Replace with actual input and output file names // convertS732_IR(inputFilePath, outputPath); // Replace with actual input and output file names convertS732_VL(inputFilePath, outputPath); return 0; }