Bayer图像说明

1、Bayer图像格式介绍

  bayer格式图片是伊士曼·柯达公司科学家Bryce Bayer发明的,Bryce Bayer所发明的拜耳阵列被广泛运用数字图像。
       

  对于彩色图像,需要采集多种最基本的颜色,如rgb三种颜色,最简单的方法就是用滤镜的方法,红色的滤镜透过红色的波长,绿色的滤镜透过绿色的波长,蓝色的滤镜透过蓝色的波长。如果要采集rgb三个基本色,则需要三块滤镜,这样价格昂贵,且不好制造,因为三块滤镜都必须保证每一个像素点都对齐。当用bayer格式的时候,很好的解决了这个问题。bayer 格式图片在一块滤镜上设置的不同的颜色,通过分析人眼对颜色的感知发现,人眼对绿色比较敏感,所以一般bayer格式的图片绿色格式的像素是是r和g像素的和。

  另外,Bayer格式是相机内部的原始图片, 一般后缀名为.raw。很多软件都可以查看, 比如PS。我们相机拍照下来存储在存储卡上的.jpeg或其它格式的图片, 都是从.raw格式转化过来的。如下图,为bayer色彩滤波阵列,由一半的G,1/4的R,1/4的B组成。
           

2、Bayer图像传感原理

  图像传感器的结构如下所示,每一个感光像素之间都有金属隔离层,光纤通过显微镜头,在色彩滤波器过滤之后,投射到相应的漏洞式硅的感光元件上。
    

  当Image Sensor往外逐行输出数据时,像素的序列为GRGRGR…/BGBGBG…(顺序RGB)。这样阵列的Sensor设计,使得RGB传感器减少到了全色传感器的1/3,如下所示。
                

3、bayer格式插值红蓝算法实现

  每一个像素仅仅包括了光谱的一部分,必须通过插值来实现每个像素的RGB值。为了从Bayer格式得到每个像素的RGB格式,我们需要通过插值填补缺失的2个色彩。插值的方法有很多(包括领域、线性、3*3等),速度与质量权衡,最好的线性插值补偿算法。其中算法如下:

  R和B通过线性领域插值,但这有四种不同的分布,如下图所示:

    A             B

    C             D
在(a)与(b)中,R和B分别取邻域的平均值。

在(c)与(d)中,取领域的4个B或R的均值作为中间像素的B值。

4、bayer格式插值绿算法实现


      E              F
由于人眼对绿光反应最敏感,对紫光和红光则反应较弱,因此为了达到更好的画质,需要对G特殊照顾。在上述(c)与(d)中,扩展开来就是上图的(e)与(f)中间像素G的取值,者也有一定的算法要求,不同的算法效果上会有差异。经过相关的研究,
(e)中间像素G值的算法如下:
      

(f)中间像素G值的算法如下:
      

  CMOS摄像头这部分转换是在内部用ADC或者ISP完成的,生产商为了降低成本必然会使得图像失真。当然用外部处理器来实现转换,如果处理器的速度足够NB,能够胜任像素的操作,用上面的算法来进行转换,皆大欢喜。不过上述算法将直接成倍提高了算法的复杂度,速度上将会有所限制。因此为了速度的提成,可以直接通过来4领域G取均值来中间像素的G值,将会降低一倍的速率,而在性能上差之甚微,算法如下:
     

  如果能够通过损失图像的额质量,来达到更快的速度,还可以取G1、G2的均值来实现,但是这样的做法会导致边沿以及跳变部分的失真。

将Bayer格式转换为tif格式

//全部.h文件
#include <iostream>
#include <vector>
#include <fstream>
#include <gdal_priv.h>
#include <gdalwarper.h>
#include <gdal.h>
#include <stdio.h>
#include <stdlib.h>
#include "j2k_mem_advance.h"
#include "format_defs.h"
#include "j2k_mem.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/io.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <memory>
#include <dirent.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <time.h>
#include <thread>
#include <stdio.h>
#include <string.h>
#include "TinyXML.h"using namespace std;
//此头文件应该是必须的部分
#include <iostream>
#include <fstream>
#include <gdal_priv.h>
#include <gdalwarper.h>
#include <gdal.h>
#include <stdio.h>
#include <stdlib.h>using namespace std;//核心代码部分
//将.dat文件读取后进行gbbr转换,最后转码为TIF文件
bool Anal_pixel(string strFilePath, string strSavePath, long nWidth, long nHeight, int nType)
{// TODO:  在此添加控件通知处理程序代码GDALAllRegister();CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");   //支持中文路径if (strFilePath == ""){return false;}const char* pszFormat = "GTIFF";GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);if (!poDriver) {return false;}//long width = 7920;//long height = 6004;long long width = nWidth;long long height = nHeight;GDALDataType gdal_data_type = GDT_UInt16;unsigned short* pData = new unsigned short[width * height];fstream sf;sf.open(strFilePath, ios::in | ios::binary);//打开文件,供读sf.seekg(0, ios::beg);//byte *bTemp = new byte[2];unsigned char* bTemp = new unsigned char[2];for (int i = 0; i < height * width; i++){sf.read((char*)&bTemp[0], sizeof(unsigned char));sf.read((char*)&bTemp[1], sizeof(unsigned char));pData[i] = bTemp[0] * 256 + bTemp[1];//char pBuff[8];//sprintf(pBuff, "%04x", pData[i]);//int isdsd = 0;}sf.close();delete[] bTemp;//----------------------解析
#pragma region 解析PointInfo** cArryAllPoint; // 二维数组cArryAllPoint = (PointInfo**)malloc(height * sizeof(PointInfo*));//height 行for (int i = 0; i < height; i++) {cArryAllPoint[i] = (PointInfo*)malloc(width * sizeof(PointInfo));//width 列}//读取文件,将文件中的数值填充for (long long y = 0; y < height; y++){for (long long x = 0; x < width / 2; x++){cArryAllPoint[y][2 * x].Point_X = 2 * x;cArryAllPoint[y][2 * x].Point_Y = y;cArryAllPoint[y][2 * x + 1].Point_X = 2 * x + 1;cArryAllPoint[y][2 * x + 1].Point_Y = y;if (y % 2 == 0){cArryAllPoint[y][2 * x].Point_B = pData[y * width / 4 + x + height * width * 1 / 2];//BcArryAllPoint[y][2 * x + 1].Point_G = pData[y * width / 2 + x];//G}else{cArryAllPoint[y][2 * x].Point_G = pData[y * width / 2 + x];//GcArryAllPoint[y][2 * x + 1].Point_R = pData[(y - 1) * width / 4 + x + height * width * 3 / 4];//R}}}delete[] pData;//释放内存//计算RGB值unsigned short R1, R2, R3, R4, B1, B2, B3, B4, G1, G2, G3, G4;for (long long y = 0; y < height; y++)//初始化数据 {for (long long x = 0; x < width; x++){if (y % 2 == 0){if (x % 2 == 0){if (x == 0){if (y == 0){R1 = 0;R2 = 0;R3 = 0;R4 = cArryAllPoint[y + 1][x + 1].Point_R;G1 = 0;G2 = 0;G3 = cArryAllPoint[y][x + 1].Point_G;G4 = cArryAllPoint[y + 1][x].Point_G;}else if (y == height - 1){R1 = 0;R2 = 0;R3 = cArryAllPoint[y - 1][x + 1].Point_R;R4 = 0;G1 = 0;G2 = cArryAllPoint[y - 1][x].Point_G;G3 = cArryAllPoint[y][x + 1].Point_G;G4 = 0;}else{R1 = 0;R2 = 0;R3 = cArryAllPoint[y - 1][x + 1].Point_R;R4 = cArryAllPoint[y + 1][x + 1].Point_R;G1 = 0;G2 = cArryAllPoint[y - 1][x].Point_G;G3 = cArryAllPoint[y][x + 1].Point_G;G4 = cArryAllPoint[y + 1][x].Point_G;}}else if (x == width - 1){if (y == 0){R1 = cArryAllPoint[y + 1][x - 1].Point_R;R2 = 0;R3 = 0;R4 = 0;G1 = cArryAllPoint[y][x - 1].Point_G;G2 = 0;G3 = 0;G4 = cArryAllPoint[y + 1][x].Point_G;}else if (y == height - 1){R1 = 0;R2 = cArryAllPoint[y - 1][x - 1].Point_R;R3 = 0;R4 = 0;G1 = cArryAllPoint[y][x - 1].Point_G;G2 = cArryAllPoint[y - 1][x].Point_G;G3 = 0;G4 = 0;}else{R1 = cArryAllPoint[y + 1][x - 1].Point_R;R2 = cArryAllPoint[y - 1][x - 1].Point_R;R3 = 0;R4 = 0;G1 = cArryAllPoint[y][x - 1].Point_G;G2 = cArryAllPoint[y - 1][x].Point_G;G3 = 0;G4 = cArryAllPoint[y + 1][x].Point_G;}}else{if (y == 0){R1 = cArryAllPoint[y + 1][x - 1].Point_R;R2 = 0;R3 = 0;R4 = cArryAllPoint[y + 1][x + 1].Point_R;G1 = cArryAllPoint[y][x - 1].Point_G;G2 = 0;G3 = cArryAllPoint[y][x + 1].Point_G;G4 = cArryAllPoint[y + 1][x].Point_G;}else if (y == height - 1){R1 = 0;R2 = cArryAllPoint[y - 1][x - 1].Point_R;R3 = cArryAllPoint[y - 1][x + 1].Point_R;R4 = 0;G1 = cArryAllPoint[y][x - 1].Point_G;G2 = cArryAllPoint[y - 1][x].Point_G;G3 = cArryAllPoint[y][x + 1].Point_G;G4 = 0;}else{R1 = cArryAllPoint[y + 1][x - 1].Point_R;R2 = cArryAllPoint[y - 1][x - 1].Point_R;R3 = cArryAllPoint[y - 1][x + 1].Point_R;R4 = cArryAllPoint[y + 1][x + 1].Point_R;G1 = cArryAllPoint[y][x - 1].Point_G;G2 = cArryAllPoint[y - 1][x].Point_G;G3 = cArryAllPoint[y][x + 1].Point_G;G4 = cArryAllPoint[y + 1][x].Point_G;}}cArryAllPoint[y][x].Point_R = (R1 + R2 + R3 + R4) / 4;cArryAllPoint[y][x].Point_G = (G1 + G2 + G3 + G4) / 4;}else{//unsigned short R1, R2, B1, B2;//G//G1,R2,G4//B1,G ,B2//G2,R1,G3//R1 = cArryAllPoint.GetAt(y - 1)->GetAt(x).Point_R;//R2 = cArryAllPoint.GetAt(y + 1)->GetAt(x).Point_R;//B1 = cArryAllPoint.GetAt(y)->GetAt(x - 1).Point_B;//B2 = cArryAllPoint.GetAt(y)->GetAt(x + 1).Point_B;if (x == 0){if (y == 0){R1 = 0;R2 = cArryAllPoint[y + 1][x].Point_R;B1 = 0;B2 = cArryAllPoint[y][x + 1].Point_B;}else if (y == height - 1){R1 = cArryAllPoint[y - 1][x].Point_R;R2 = 0;B1 = 0;B2 = cArryAllPoint[y][x + 1].Point_B;}else{R1 = cArryAllPoint[y - 1][x].Point_R;R2 = cArryAllPoint[y + 1][x].Point_R;B1 = 0;B2 = cArryAllPoint[y][x + 1].Point_B;}}else if (x == width - 1){if (y == 0){R1 = 0;R2 = cArryAllPoint[y + 1][x].Point_R;B1 = cArryAllPoint[y][x - 1].Point_B;B2 = 0;}else if (y == height - 1){R1 = cArryAllPoint[y - 1][x].Point_R;R2 = 0;B1 = cArryAllPoint[y][x - 1].Point_B;B2 = 0;}else{R1 = cArryAllPoint[y - 1][x].Point_R;R2 = cArryAllPoint[y + 1][x].Point_R;B1 = cArryAllPoint[y][x - 1].Point_B;B2 = 0;}}else{if (y == 0){R1 = 0;R2 = cArryAllPoint[y + 1][x].Point_R;B1 = cArryAllPoint[y][x - 1].Point_B;B2 = cArryAllPoint[y][x + 1].Point_B;}else if (y == height - 1){R1 = cArryAllPoint[y - 1][x].Point_R;R2 = 0;B1 = cArryAllPoint[y][x - 1].Point_B;B2 = cArryAllPoint[y][x + 1].Point_B;}else{R1 = cArryAllPoint[y - 1][x].Point_R;R2 = cArryAllPoint[y + 1][x].Point_R;B1 = cArryAllPoint[y][x - 1].Point_B;B2 = cArryAllPoint[y][x + 1].Point_B;}}cArryAllPoint[y][x].Point_R = (R1 + R2) / 2;cArryAllPoint[y][x].Point_B = (B1 + B2) / 2;}}else{if (x % 2 == 0){//unsigned short R1, R2, B1, B2;//G//G1,B2,G4//R1,G ,R2//G2,B1,G3//R1 = cArryAllPoint.GetAt(y)->GetAt(x - 1).Point_R;//R2 = cArryAllPoint.GetAt(y)->GetAt(x + 1).Point_R;//B1 = cArryAllPoint.GetAt(y - 1)->GetAt(x).Point_B;//B2 = cArryAllPoint.GetAt(y + 1)->GetAt(x).Point_B;if (x == 0){if (y == 0){R1 = 0;R2 = cArryAllPoint[y][x + 1].Point_R;B1 = 0;B2 = cArryAllPoint[y + 1][x].Point_B;}else if (y == height - 1){R1 = 0;R2 = cArryAllPoint[y][x + 1].Point_R;B1 = cArryAllPoint[y - 1][x].Point_B;B2 = 0;}else{R1 = 0;R2 = cArryAllPoint[y][x + 1].Point_R;B1 = cArryAllPoint[y - 1][x].Point_B;B2 = cArryAllPoint[y + 1][x].Point_B;}}else if (x == width - 1){if (y == 0){R1 = cArryAllPoint[y][x - 1].Point_R;R2 = 0;B1 = 0;B2 = cArryAllPoint[y + 1][x].Point_B;}else if (y == height - 1){R1 = cArryAllPoint[y][x - 1].Point_R;R2 = 0;B1 = cArryAllPoint[y - 1][x].Point_B;B2 = 0;}else{R1 = cArryAllPoint[y][x - 1].Point_R;R2 = 0;B1 = cArryAllPoint[y - 1][x].Point_B;B2 = cArryAllPoint[y + 1][x].Point_B;}}else{if (y == 0){R1 = cArryAllPoint[y][x - 1].Point_R;R2 = cArryAllPoint[y][x + 1].Point_R;B1 = 0;B2 = cArryAllPoint[y + 1][x].Point_B;}else if (y == height - 1){R1 = cArryAllPoint[y][x - 1].Point_R;R2 = cArryAllPoint[y][x + 1].Point_R;B1 = cArryAllPoint[y - 1][x].Point_B;B2 = 0;}else{R1 = cArryAllPoint[y][x - 1].Point_R;R2 = cArryAllPoint[y][x + 1].Point_R;B1 = cArryAllPoint[y - 1][x].Point_B;B2 = cArryAllPoint[y + 1][x].Point_B;}}cArryAllPoint[y][x].Point_R = (R1 + R2) / 2;cArryAllPoint[y][x].Point_B = (B1 + B2) / 2;}else{//unsigned short B1, B2, B3, B4, G1, G2, G3, G4;//R//B1,G4,B4//G1,R ,G3//B2,G2,B3//B1 = cArryAllPoint.GetAt(y + 1)->GetAt(x - 1).Point_B;//B2 = cArryAllPoint.GetAt(y - 1)->GetAt(x - 1).Point_B;//B3 = cArryAllPoint.GetAt(y - 1)->GetAt(x + 1).Point_B;//B4 = cArryAllPoint.GetAt(y + 1)->GetAt(x + 1).Point_B;//G1 = cArryAllPoint.GetAt(y)->GetAt(x - 1).Point_G;//G2 = cArryAllPoint.GetAt(y - 1)->GetAt(x).Point_G;//G3 = cArryAllPoint.GetAt(y)->GetAt(x + 1).Point_G;//G4 = cArryAllPoint.GetAt(y + 1)->GetAt(x).Point_G;if (x == 0){//不存在 X=0}else if (x == width - 1){if (y == 0){//不存在 Y=0}else if (y == height - 1){B1 = 0;B2 = cArryAllPoint[y - 1][x - 1].Point_B;B3 = 0;B4 = 0;G1 = cArryAllPoint[y][x - 1].Point_G;G2 = cArryAllPoint[y - 1][x].Point_G;G3 = 0;G4 = 0;}else{B1 = cArryAllPoint[y + 1][x - 1].Point_B;B2 = cArryAllPoint[y - 1][x - 1].Point_B;B3 = 0;B4 = 0;G1 = cArryAllPoint[y][x - 1].Point_G;G2 = cArryAllPoint[y - 1][x].Point_G;G3 = 0;G4 = cArryAllPoint[y + 1][x].Point_G;}}else{if (y == 0){//不存在 Y=0}else if (y == height - 1){B1 = 0;B2 = cArryAllPoint[y - 1][x - 1].Point_B;B3 = cArryAllPoint[y - 1][x + 1].Point_B;B4 = 0;G1 = cArryAllPoint[y][x - 1].Point_G;G2 = cArryAllPoint[y - 1][x].Point_G;G3 = cArryAllPoint[y][x + 1].Point_G;G4 = 0;}else{B1 = cArryAllPoint[y + 1][x - 1].Point_B;B2 = cArryAllPoint[y - 1][x - 1].Point_B;B3 = cArryAllPoint[y - 1][x + 1].Point_B;B4 = cArryAllPoint[y + 1][x + 1].Point_B;G1 = cArryAllPoint[y][x - 1].Point_G;G2 = cArryAllPoint[y - 1][x].Point_G;G3 = cArryAllPoint[y][x + 1].Point_G;G4 = cArryAllPoint[y + 1][x].Point_G;}}cArryAllPoint[y][x].Point_B = (B1 + B2 + B3 + B4) / 4;cArryAllPoint[y][x].Point_G = (G1 + G2 + G3 + G4) / 4;}}}}//整合到pDataRGB中//unsigned char * pDataRGB = new unsigned char[width * height * 3];unsigned short** newbuffs = new unsigned short* [3]; // 1, 2, 3 : r g b newbuffs[0] = new unsigned short[width * height];newbuffs[1] = new unsigned short[width * height];newbuffs[2] = new unsigned short[width * height];double dTemp;for (long long y = 0; y < height; y++)//初始化数据{for (long long x = 0; x < width; x++){dTemp = (double)cArryAllPoint[y][x].Point_R;newbuffs[0][y * width + x] = (unsigned short)dTemp;dTemp = (double)cArryAllPoint[y][x].Point_G;newbuffs[1][y * width + x] = (unsigned short)dTemp;dTemp = (double)cArryAllPoint[y][x].Point_B;newbuffs[2][y * width + x] = (unsigned short)dTemp;}}double minDN[3] = { 0 };//统计最小的DN值double maxDN[3] = { 0 };//统计最大的DN值//释放内存 cArryAllPointfor (int i = 0; i < height; i++){delete[] cArryAllPoint[i];}free(cArryAllPoint);//将原数据进行拉伸放大for (long long m = 0; m < height; m++){for (long long n = 0; n < width; n++){for (long long i = 0; i < 3; i++){if (newbuffs[i][m * width + n] < minDN[i])minDN[i] = newbuffs[i][m * width + n];if (newbuffs[i][m * width + n] > maxDN[i])maxDN[i] = newbuffs[i][m * width + n];}}}for (long long i = 0; i < 3; i++){for (long long m = 0; m < height*width; m++){newbuffs[i][m] = (newbuffs[i][m] - minDN[i]) * 1.0 / (maxDN[i] - minDN[i]) * 65535;}}#pragma endregionif (nType == 0)//拉伸后的图像{char** papszOptions = nullptr;papszOptions = CSLSetNameValue(papszOptions, "INTERLEAVE", "BAND");papszOptions = CSLSetNameValue(papszOptions, "BIGTIFF", "IF_NEEDED");const char* pszDstFilename = strSavePath.c_str();GDALDataset* poDstDS = poDriver->Create(pszDstFilename, width, height, 3, GDT_UInt16, papszOptions);if (!poDstDS) {for (int i = 0; i < 3; i++){delete[] newbuffs[i];}free(newbuffs);return false;}int bandMap[3] = { 1, 2, 3 };for (int i = 0; i < 3; i++){poDstDS->GetRasterBand(i + 1)->RasterIO(GF_Write, 0, 0, width, height, newbuffs[i], width, height, GDT_UInt16, 0, 0, 0);delete[] newbuffs[i];}free(newbuffs);GDALClose((GDALDatasetH)poDstDS);}else{//针对原图16位的值进行高8位、低8位、中8位的转换。unsigned char** newbuffs1 = new unsigned char* [3]; // 1, 2, 3 : r g b newbuffs1[0] = new unsigned char[width * height];newbuffs1[1] = new unsigned char[width * height];newbuffs1[2] = new unsigned char[width * height];for (long long i = 0; i < 3; i++){for (long long m = 0; m < height; m++){for (long long n = 0; n < width; n++){char pBuff[4], pBuff2[8];if (nType == 1)//高8{newbuffs1[i][m * width + n] = newbuffs[i][m * width + n] / 4;//------G8}else if (nType == 2)//中8{newbuffs1[i][m * width + n] = newbuffs[i][m * width + n] / 2;//-------M8}else if (nType == 3)//低8{newbuffs1[i][m * width + n] = newbuffs[i][m * width + n];//------D8}}}}char** papszOptions = nullptr;papszOptions = CSLSetNameValue(papszOptions, "INTERLEAVE", "BAND");papszOptions = CSLSetNameValue(papszOptions, "BIGTIFF", "IF_NEEDED");const char* pszDstFilename = strSavePath.c_str();GDALDataset* poDstDS = poDriver->Create(pszDstFilename, width, height, 3, GDT_Byte, papszOptions);if (!poDstDS) {for (int i = 0; i < 3; i++){delete[] newbuffs[i];delete[] newbuffs1[i];}return false;}int bandMap[3] = { 1, 2, 3 };for (int i = 0; i < 3; i++){poDstDS->GetRasterBand(i + 1)->RasterIO(GF_Write, 0, 0, width, height, newbuffs1[i], width, height, GDT_Byte, 0, 0, 0);delete[] newbuffs[i];delete[] newbuffs1[i];}GDALClose((GDALDatasetH)poDstDS);}return true;
}

第一次书写博客会有些许乱,有需求的可以私我或者留言询问具体问题。

参考文件:

感谢作者:
淇淇宝贝   https://www.cnblogs.com/qiqibaby/p/5267566.html

C++ Bayer图像格式,使用GDAL进行格式转换。相关推荐

  1. MIPI RAW和YUV常见图像格式的解析、格式转换和看图软件

    设计初衷 在ISP的图像算法开发中,经常会涉及到YUV.RAW等格式的图像.例如,在YUV域,经常会涉及到I420.NV12和P010等数据格式之间的转换.在RAW域,又会经常涉及到MIPI RAW等 ...

  2. 图像格式及Matlab的格式转换

    1. matlab图像保存说明 matlab中读取图片后保存的数据是uint8类型(8位无符号整数,即1个字节),以此方式存储的图像称作8位图像,好处相比较默认matlab数据类型双精度浮点doubl ...

  3. Python:图片格式转换

    JPG格式图片转PNG格式 png和jpg最大的不同点在于png支持alpha通道,也就是我们说的透明通道,而jpg是不支持透明通道的,这就使得png格式在某些场合具有特殊的用途. RGBA是代表Re ...

  4. DDSM数据库转换图像格式——LJPEG转为PNG格式

    Digital Database for Screening Mammography (DDSM)数据库是一个非常大的乳腺图像数据库,有一万多张图像,但是图像格式是LJPEG,现有的图像软件(如pho ...

  5. JAVA调用GDAL实现影像格式转换,以tif to jpg为例

    前言 本文简单实现java调用GDAL实现影像格式转换. package Marcus.com;import org.gdal.gdal.Dataset; import org.gdal.gdal.D ...

  6. FFmpeg学习4:音频格式转换

    前段时间,在学习试用FFmpeg播放音频的时候总是有杂音,网上的很多教程是基于之前版本的FFmpeg的,而新的FFmepg3中audio增加了平面(planar)格式,而SDL播放音频是不支持平面格式 ...

  7. 常用图像格式(PNG,JPG)到SGI图像格式(RGB,BW)的转换

    常用图像格式(PNG,JPG)到SGI图像格式(RGB,BW)的转换 网站链接 根据该网站的描述和给的相应例子,自己改写了一个把png,jpg等常用格式的图片转化为rgb,bw格式的代码. #incl ...

  8. c语言bmp转换jpeg_PDF格式转换工具

    Cisdem PDF Converter OCR for Mac是一款Mac平台的PDF格式转换工具,可以帮助我们将PDF格式的文件转换成Word, Text, Excel, ePub, Keynot ...

  9. 使用GDAL下载并转换SRTM的DEM数据(一)

    有时候需要用到DEM数据,常用的免费的DEM数据就是SRTM的DEM数据. SRTM数据主要是由美国太空总署(NASA)和国防部国家测绘局(NIMA)联合测量的,SRTM的全称是Shuttle Rad ...

  10. 如何利用 onlyoffice 实现文档格式转换

    目录 前言 正文 启动 onlyoffice 服务 API 接口介绍 转换列表 请求示例 结尾 前言 日常生活和工作中,文档格式转换应该是很常见的需求.面对这样的需求,我们技术男有没有属于自己的好方法 ...

最新文章

  1. 五大晶元厂的内存型号命名方式
  2. C++实现删除字符串中所有重复出现的字符
  3. JAVA虚拟机体系结构
  4. python中模块(Module)和包(Package)的区别 (导入模块、导入包)(import导包)
  5. Vue——全局element-resize-detector监听DOM元素
  6. Map map = request.getParameterMap(); BeanUtils.populate(bean, map);对前端表单的迅速封装与判断
  7. 计算机数媒专业优势,27所院校新开设数字媒体艺术专业,“数媒”专业为什么这么火?...
  8. edite not the main type
  9. springboot系列二、springboot项目搭建
  10. 腾讯云独立模式账号引入接口
  11. The Semantics of Constructors(拷贝构造函数之编译背后的行为)
  12. 运动控制器RTEX总线使用入门
  13. zigbee学习之JN5169 串口UARTs
  14. SharePoint 集成PowerApps和Flow教程(一,搭建PowerApps 环境)
  15. 电脑开机显示器黑屏是什么原因,电脑显示器黑屏怎么办
  16. 莫纳什大学计算机专业录取要求,2020年莫纳什大学计算机信息硕士申请条件
  17. 华为OD机试用Python实现 -【查找树中的元素 or 查找二叉树节点】(2023-Q1 新题)
  18. 使用证件照api接口快速上线证件照业务-超详细!
  19. OpenCL编程初探
  20. 唇语识别!AI 领域的下一个万亿市场?

热门文章

  1. 梅特勒托利多xk3124电子秤说明书_托利多电子秤说明书
  2. 工作积累10——推荐一本看过最好的数据分析的书
  3. 京东充值系统现漏洞 被恶意盗刷
  4. Nginx搭建虚拟主机环境
  5. 【有料c++题目周刊 | 第一期】希腊诸神
  6. DELL服务器 一般内存模块安装原则
  7. python — numpy计算矩阵特征值,特征向量
  8. PHP Yar - 学习/实践
  9. IntelliJ IDEA 在 Project 选项卡中查找快捷键
  10. 计算机开机连不上网,我家电脑有时候开机为什么连不上网,重启以后就好?