OpenCL的学习---矩阵转置问题及用FreeImage保存灰度图

对灰度图像矩阵转置:图像宽1080 高720


kernel:

__kernel void transposeMatrix(__global uchar* srcimgdata,__global uchar* dstimgdata,int width,int height)
{
	int id=get_global_id(0);
	for(int i=id;i<width*height;i+=get_global_size(0))
	{
		int dstcol=i/1080;
		int dstrow=i%1080;
		dstimgdata[dstrow*height+dstcol]=srcimgdata[i];	
	}
}
host端:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <CL/cl.h>
#include "gFreeImage.h"

void check(cl_int status) {

   if (status != CL_SUCCESS) {
      printf("OpenCL error (%d)\n", status);
      exit(-1);
   }
}
char* readFile(const char *filename) {

   FILE *fp;
   char *fileData;
   long fileSize;

   /* Open the file */
   fp = fopen(filename, "r");
   if (!fp) {
      printf("Could not open file: %s\n", filename);
      exit(-1);
   }

   /* Determine the file size */
   if (fseek(fp, 0, SEEK_END)) {
      printf("Error reading the file\n");
      exit(-1);
   }
   fileSize = ftell(fp);
   if (fileSize < 0) {
      printf("Error reading the file\n");
      exit(-1);
   }
   if (fseek(fp, 0, SEEK_SET)) {
      printf("Error reading the file\n");
      exit(-1);
   }

   /* Read the contents */
   fileData = (char*)malloc(fileSize + 1);
   if (!fileData) {
      exit(-1);
   }
   if (fread(fileData, fileSize, 1, fp) != 1) {
      printf("Error reading the file\n");
      exit(-1);
   }

   /* Terminate the string */
   fileData[fileSize] = '\0';

   /* Close the file */
   if (fclose(fp)) {
      printf("Error closing the file\n");
      exit(-1);
   }

   return fileData;
}

int main()
{
   cl_int status;
   cl_platform_id platform;
   status = clGetPlatformIDs(1, &platform, NULL);
   check(status);
   cl_device_id device;
   status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL);
   check(status);
   cl_context context;
   context = clCreateContext(NULL, 1, &device, NULL, NULL, &status);
   check(status);
   cl_command_queue cmdQueue=clCreateCommandQueue(context, device, 0, &status);
   check(status);

   int imageCols, imageRows;
	gFreeImage img;
	int readflag=img.LoadImageGrey("/home/jumper/OpenCL_projects/MatrixTransposition/cat.bmp");
	unsigned char *hInputImage = img.getImageDataGrey(imageCols,imageRows);
	const int imageElements = imageRows*imageCols;
	const size_t imageSize = imageElements*sizeof(unsigned char);

   cl_mem  bufInputImage = clCreateBuffer(context, CL_MEM_READ_ONLY, imageSize, NULL,&status);
   cl_mem  bufOutputImage = clCreateBuffer(context, CL_MEM_WRITE_ONLY, imageSize, NULL,&status);
   check(status);
   int zero = 0;
   status = clEnqueueFillBuffer(cmdQueue, bufOutputImage, &zero,sizeof(int), 0, imageSize, 0, NULL, NULL);
   check(status);
   status = clEnqueueWriteBuffer(cmdQueue, bufInputImage, CL_TRUE, 0, imageSize,(void*)hInputImage, 0, NULL, NULL);
   check(status);

   char *programSource = readFile("/home/jumper/OpenCL_projects/MatrixTransposition/mine.cl");
   size_t programSourceLen = strlen(programSource);
   cl_program program = clCreateProgramWithSource(context, 1,(const char**)&programSource, &programSourceLen, &status);
   check(status);
   status = clBuildProgram(program, 1, &device, NULL, NULL, NULL);
   //std::cout<<status<<std::endl;
   if (status != CL_SUCCESS) {
	   printf("cannot build program successfully!\n");
	   size_t logSize;
	  status = clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG,0, NULL, &logSize);
	  char *log = (char*)malloc(logSize);
	  status = clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG,logSize, log, NULL);
	  printf("%s\n", log);
	  free(log);
      exit(-1);
   }
   cl_kernel kernel;
   kernel = clCreateKernel(program, "transposeMatrix", &status);
   check(status);
   status  = clSetKernelArg(kernel, 0, sizeof(cl_mem), &bufInputImage);
   status |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &bufOutputImage);
   status |= clSetKernelArg(kernel, 2, sizeof(int), &imageCols);
   status |= clSetKernelArg(kernel, 3, sizeof(int), &imageRows);
   check(status);

   size_t globalWorkSize[1]={1024};
   size_t localWorkSize[1]={128};
   status = clEnqueueNDRangeKernel(cmdQueue, kernel, 1, NULL,globalWorkSize, localWorkSize, 0, NULL, NULL);
   std::cout<<status<<std::endl;
   check(status);

   unsigned char*Outputimg = (unsigned char*)malloc(imageSize);
   if (!Outputimg) { exit(-1); }
   status = clEnqueueReadBuffer(cmdQueue, bufOutputImage, CL_TRUE, 0,imageSize, Outputimg, 0, NULL, NULL);
   check(status);

   for(int i = 0; i < imageSize; i++)
   	{
	   hInputImage[i] =Outputimg[i];
   	}
   img.SaveImage("/home/jumper/OpenCL_projects/MatrixTransposition/cat_transposition.bmp");

   clReleaseKernel(kernel);
   clReleaseProgram(program);
   clReleaseCommandQueue(cmdQueue);
   clReleaseMemObject(bufInputImage);
   clReleaseMemObject(bufOutputImage);
   clReleaseContext(context);
   free(Outputimg);
   free(programSource);

   return 0;
}
结果:

还存在问题,我再想想。

找到FreeImage库中新建一幅指定大小的图 :

#include "gFreeImage.h"
bool SaveImage(char *fileName,unsigned char *buffer, int width, int height)
{
    FREE_IMAGE_FORMAT format = FreeImage_GetFIFFromFilename(fileName);
    FIBITMAP *image = FreeImage_ConvertFromRawBits((BYTE*)buffer, height,width, height, 8,0, 0, 0);
    return (FreeImage_Save(format, image, fileName) == TRUE) ? true : false;
}
用它保存,但保存出来是全黑的 如 https://sourceforge.net/p/freeimage/discussion/36110/thread/17f61136/  遇到的一样。可以保存彩图 但灰度图保存出来是黑的。why?

这个问题至今没解决 谷歌到 http://m.blog.naver.com/sogangori/220701976219  一个韩国人写的FreeImage的读写图像  第4点和第5点分别是将数据保存为灰度图保存至本地、将数据保存为彩图 但我试了 只有彩图是成功的  灰度图出来始终是全黑:


结果:


如果有人知道,请告知。


我写了个简单的矩阵转置做实验:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <CL/cl.h>
#include "gFreeImage.h"
void check(cl_int status);
char* readFile(const char *filename);
int main()
{
   cl_int status;
   cl_platform_id platform;
   status = clGetPlatformIDs(1, &platform, NULL);
   check(status);
   cl_device_id device;
   status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL);
   check(status);
   cl_context context;
   context = clCreateContext(NULL, 1, &device, NULL, NULL, &status);
   check(status);
   cl_command_queue cmdQueue=clCreateCommandQueue(context, device, 0, &status);
   check(status);

   int imageCols=3, imageRows=4;
   size_t imageSize=imageCols*imageRows*sizeof(int);
   int *hInputImage=(int*)malloc(imageSize);
   std::cout<<"input matrix..."<<std::endl;
   for(int i=0;i<imageRows;i++)
   {
	   for(int j=0;j<imageCols;j++)
	   {
		   int init=i+j*2;
		   hInputImage[i*imageCols+j]=init;
		   std::cout<<init<<" ";
	   }
	   std::cout<<std::endl;
   }
   std::cout<<std::endl;

   cl_mem  bufInputImage = clCreateBuffer(context, CL_MEM_READ_ONLY, imageSize, NULL,&status);
   cl_mem  bufOutputImage = clCreateBuffer(context, CL_MEM_WRITE_ONLY, imageSize, NULL,&status);
   check(status);
   int zero = 0;
   status = clEnqueueFillBuffer(cmdQueue, bufOutputImage, &zero,sizeof(int), 0, imageSize, 0, NULL, NULL);
   check(status);
   status = clEnqueueWriteBuffer(cmdQueue, bufInputImage, CL_TRUE, 0, imageSize,(void*)hInputImage, 0, NULL, NULL);
   check(status);

   char *programSource = readFile("/home/jumper/OpenCL_projects/MatrixTransposition/notImg.cl");
   size_t programSourceLen = strlen(programSource);
   cl_program program = clCreateProgramWithSource(context, 1,(const char**)&programSource, &programSourceLen, &status);
   check(status);
   status = clBuildProgram(program, 1, &device, NULL, NULL, NULL);
   //std::cout<<status<<std::endl;
   if (status != CL_SUCCESS) {
	   printf("cannot build program successfully!\n");
	   size_t logSize;
	  status = clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG,0, NULL, &logSize);
	  char *log = (char*)malloc(logSize);
	  status = clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG,logSize, log, NULL);
	  printf("%s\n", log);
	  free(log);
      exit(-1);
   }

   cl_kernel kernel;
   kernel = clCreateKernel(program, "transpose", &status);
   check(status);
   status  = clSetKernelArg(kernel, 0, sizeof(cl_mem), &bufInputImage);
   status |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &bufOutputImage);
   status |= clSetKernelArg(kernel, 2, sizeof(int), &imageCols);
   status |= clSetKernelArg(kernel, 3, sizeof(int), &imageRows);
   check(status);

   size_t globalWorkSize[1]={3};
   size_t localWorkSize[1]={1};
   status = clEnqueueNDRangeKernel(cmdQueue, kernel, 1, NULL,globalWorkSize, localWorkSize, 0, NULL, NULL);
   //std::cout<<status<<std::endl;
   check(status);

   int*Outputimg = (int*)malloc(imageSize);
   if (!Outputimg) { exit(-1); }
   status = clEnqueueReadBuffer(cmdQueue, bufOutputImage, CL_TRUE, 0,imageSize, Outputimg, 0, NULL, NULL);
   check(status);
   std::cout<<"transpose matrix..."<<std::endl;
   for(int i=0;i<imageCols;i++)
   {
	   for(int j=0;j<imageRows;j++)
	   {
		   int pos=i*imageRows+j;
		   std::cout<<Outputimg[pos]<<" ";
	   }
	   std::cout<<std::endl;
   }

   clReleaseKernel(kernel);
   clReleaseProgram(program);
   clReleaseCommandQueue(cmdQueue);
   clReleaseMemObject(bufInputImage);
   clReleaseMemObject(bufOutputImage);
   clReleaseContext(context);
   free(Outputimg);
   free(programSource);
   free(hInputImage);

   return 0;
}
cl文件:

__kernel void transpose(__global int* srcimgdata,__global int* dstimgdata,int width,int height)
{
	int id=get_global_id(0);
	for(int i=id;i<width*height;i+=get_global_size(0))
	{
		int dstcol=i/width;
		int dstrow=i%width;
		dstimgdata[dstrow*height+dstcol]=srcimgdata[i];	
	}
}
结果转置出来是正确的:




猫的图片转置的我改成了:

main部分,cl部分没有改。

bool SaveGreyimg(char* file,unsigned char* data,int width,int height){
	FIBITMAP* bitmap=FreeImage_Allocate(width,height,1);
	BYTE *src=new BYTE[width*height*1];
	for(int i=0;i<width*height;i++)
		src[i]=data[i];
	FIBITMAP* Image=FreeImage_ConvertFromRawBits(src,width,height,1,8,0,0,0,false);
	FreeImage_Save(FIF_JPEG,Image,file,JPEG_BASELINE);
	FreeImage_Unload(Image);
}

int main()
{
   cl_int status;
   cl_platform_id platform;
   status = clGetPlatformIDs(1, &platform, NULL);
   //check(status);
   cl_device_id device;
   status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL);
   //check(status);
   cl_context context;
   context = clCreateContext(NULL, 1, &device, NULL, NULL, &status);
   //check(status);
   cl_command_queue cmdQueue=clCreateCommandQueue(context, device, 0, &status);
   //check(status);

   int imageCols, imageRows;
	gFreeImage img;
	int readflag=img.LoadImageGrey("/home/jumper/OpenCL_projects/MatrixTransposition/cat.bmp");
	unsigned char *hInputImage = img.getImageDataGrey(imageCols,imageRows);
	const int imageElements = imageRows*imageCols;
	const size_t imageSize = imageElements*sizeof(unsigned char);

   cl_mem  bufInputImage = clCreateBuffer(context, CL_MEM_READ_ONLY, imageSize, NULL,&status);
   cl_mem  bufOutputImage = clCreateBuffer(context, CL_MEM_WRITE_ONLY, imageSize, NULL,&status);
   //check(status);
   int zero = 0;
   status = clEnqueueFillBuffer(cmdQueue, bufOutputImage, &zero,sizeof(int), 0, imageSize, 0, NULL, NULL);
   //check(status);
   status = clEnqueueWriteBuffer(cmdQueue, bufInputImage, CL_TRUE, 0, imageSize,(void*)hInputImage, 0, NULL, NULL);
   //check(status);

   char *programSource = readFile("/home/jumper/OpenCL_projects/MatrixTransposition/mine.cl");
   size_t programSourceLen = strlen(programSource);
   cl_program program = clCreateProgramWithSource(context, 1,(const char**)&programSource, &programSourceLen, &status);
   //check(status);
   status = clBuildProgram(program, 1, &device, NULL, NULL, NULL);
   //std::cout<<status<<std::endl;
   if (status != CL_SUCCESS) {
	   printf("cannot build program successfully!\n");
	   size_t logSize;
	  status = clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG,0, NULL, &logSize);
	  char *log = (char*)malloc(logSize);
	  status = clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG,logSize, log, NULL);
	  printf("%s\n", log);
	  free(log);
      exit(-1);
   }


   cl_kernel kernel;
   kernel = clCreateKernel(program, "transposeMatrix", &status);
   //check(status);
   status  = clSetKernelArg(kernel, 0, sizeof(cl_mem), &bufInputImage);
   status |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &bufOutputImage);
   status |= clSetKernelArg(kernel, 2, sizeof(int), &imageCols);
   status |= clSetKernelArg(kernel, 3, sizeof(int), &imageRows);
   //check(status);

   size_t globalWorkSize[1]={1024};
   size_t localWorkSize[1]={128};
   status = clEnqueueNDRangeKernel(cmdQueue, kernel, 1, NULL,globalWorkSize, localWorkSize, 0, NULL, NULL);
   //std::cout<<status<<std::endl;
   //check(status);

   unsigned char*Outputimg = (unsigned char*)malloc(imageSize);
   if (!Outputimg) { exit(-1); }
   status = clEnqueueReadBuffer(cmdQueue, bufOutputImage, CL_TRUE, 0,imageSize, Outputimg, 0, NULL, NULL);
   //check(status);
   SaveGreyimg("/home/jumper/OpenCL_projects/MatrixTransposition/transpose.jpg",Outputimg,imageRows,imageCols);

//	use FreeImage to save greyscaled image but failed below!
//   FIBITMAP* bitmap=FreeImage_Allocate(128,128,1);
//	BYTE *src=new BYTE[128*128*1];
//	for(int i=0;i<128*128;i++)
//		src[i]=i;
//	FIBITMAP* Image=FreeImage_ConvertFromRawBits(src,128,128,128,8,0,0,0,false);
//	FreeImage_Save(FIF_PNG,Image,"wdtest.png",0);
//	FreeImage_Unload(Image);
//	use FreeImage to save color image succeed.
//   FIBITMAP* bitmap=FreeImage_Allocate(16,16,3);
//	BYTE *src=new BYTE[1024*720*3];
//	for(int i=0;i<1024*720;i++){
//		src[i*3]=i;
//		src[i*3+1]=i;
//		src[i*3+2]=200;
//	}
//	FIBITMAP* Image=FreeImage_ConvertFromRawBits(src,1024,720,1024*3,8*3,0,0,0,false);
//	FreeImage_Save(FIF_BMP,Image,"saveimg2.bmp");
//	FreeImage_Unload(Image);

	std::cout<<FreeImage_GetVersion()<<std::endl;

   clReleaseKernel(kernel);
   clReleaseProgram(program);
   clReleaseCommandQueue(cmdQueue);
   clReleaseMemObject(bufInputImage);
   clReleaseMemObject(bufOutputImage);
   clReleaseContext(context);
   free(Outputimg);
   free(programSource);

   return 0;
}
但仍旧是一张全黑的图片啊!

但我将返回于host的这个buffer输出即将这个Outputimg去统计非0值 有很多非0啊,怎么保存时竟然是转置后的黑图呢?所以只有一种可能,保存的函数时出错了?刚刚已经自我解决,但我不是用的FreeImage 而是改用了opencv实现返回host端的buffer保存为灰度图。 但用FreeImage实现的我已经放弃了。如果有大神知道,也可以告诉我。

我最后的:main.cpp:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <CL/cl.h>
#include "gFreeImage.h"
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
char* readFile(const char *filename);

//bool SaveImage(char *fileName,unsigned char *buffer, int width, int height)
//{
//    FREE_IMAGE_FORMAT format = FreeImage_GetFIFFromFilename(fileName);
//    FIBITMAP *image = FreeImage_ConvertFromRawBits((BYTE*)buffer, width,height,1, 8,0, 0, 0,false);
//    return (FreeImage_Save(format, image, fileName) == TRUE) ? true : false;
//}

bool SaveGreyimg(char* file,unsigned char* data,int width,int height){
	FIBITMAP* bitmap=FreeImage_Allocate(width,height,1);
	BYTE *src=new BYTE[width*height*1];
	for(int i=0;i<width*height;i++)
		src[i]=data[i];
	FIBITMAP* Image=FreeImage_ConvertFromRawBits(src,width,height,1,8,0,0,0,false);
	FreeImage_Save(FIF_JPEG,Image,file,JPEG_BASELINE);
	FreeImage_Unload(Image);
}

int main()
{
   cl_int status;
   cl_platform_id platform;
   status = clGetPlatformIDs(1, &platform, NULL);
   //check(status);
   cl_device_id device;
   status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL);
   //check(status);
   cl_context context;
   context = clCreateContext(NULL, 1, &device, NULL, NULL, &status);
   //check(status);
   cl_command_queue cmdQueue=clCreateCommandQueue(context, device, 0, &status);
   //check(status);

   int imageCols, imageRows;
	gFreeImage img;
	int readflag=img.LoadImageGrey("/home/jumper/OpenCL_projects/MatrixTransposition/cat.bmp");
	unsigned char *hInputImage = img.getImageDataGrey(imageCols,imageRows);
	const int imageElements = imageRows*imageCols;
	const size_t imageSize = imageElements*sizeof(unsigned char);

   cl_mem  bufInputImage = clCreateBuffer(context, CL_MEM_READ_ONLY, imageSize, NULL,&status);
   cl_mem  bufOutputImage = clCreateBuffer(context, CL_MEM_WRITE_ONLY, imageSize, NULL,&status);
   //check(status);
   int zero = 0;
   status = clEnqueueFillBuffer(cmdQueue, bufOutputImage, &zero,sizeof(int), 0, imageSize, 0, NULL, NULL);
   //check(status);
   status = clEnqueueWriteBuffer(cmdQueue, bufInputImage, CL_TRUE, 0, imageSize,(void*)hInputImage, 0, NULL, NULL);
   //check(status);

   char *programSource = readFile("/home/jumper/OpenCL_projects/MatrixTransposition/mine.cl");
   size_t programSourceLen = strlen(programSource);
   cl_program program = clCreateProgramWithSource(context, 1,(const char**)&programSource, &programSourceLen, &status);
   //check(status);
   status = clBuildProgram(program, 1, &device, NULL, NULL, NULL);
   //std::cout<<status<<std::endl;
   if (status != CL_SUCCESS) {
	   printf("cannot build program successfully!\n");
	   size_t logSize;
	  status = clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG,0, NULL, &logSize);
	  char *log = (char*)malloc(logSize);
	  status = clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG,logSize, log, NULL);
	  printf("%s\n", log);
	  free(log);
      exit(-1);
   }


   cl_kernel kernel;
   kernel = clCreateKernel(program, "transposeMatrix", &status);
   //check(status);
   status  = clSetKernelArg(kernel, 0, sizeof(cl_mem), &bufInputImage);
   status |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &bufOutputImage);
   status |= clSetKernelArg(kernel, 2, sizeof(int), &imageCols);
   status |= clSetKernelArg(kernel, 3, sizeof(int), &imageRows);
   //check(status);

   size_t globalWorkSize[1]={1024};
   size_t localWorkSize[1]={128};
   status = clEnqueueNDRangeKernel(cmdQueue, kernel, 1, NULL,globalWorkSize, localWorkSize, 0, NULL, NULL);
   //std::cout<<status<<std::endl;
   //check(status);

   unsigned char*Outputimg = (unsigned char*)malloc(imageSize);
   if (!Outputimg) { exit(-1); }
   status = clEnqueueReadBuffer(cmdQueue, bufOutputImage, CL_TRUE, 0,imageSize, Outputimg, 0, NULL, NULL);

   Mat dstimg=Mat(imageCols,imageRows,CV_8UC1,Outputimg);
   imwrite("dstimg.jpg",dstimg);
   SaveGreyimg("/home/jumper/OpenCL_projects/MatrixTransposition/transpose.jpg",Outputimg,imageRows,imageCols);

//	use FreeImage to save greyscaled image but failed below!
//   FIBITMAP* bitmap=FreeImage_Allocate(128,128,1);
//	BYTE *src=new BYTE[128*128*1];
//	for(int i=0;i<128*128;i++)
//		src[i]=i;
//	FIBITMAP* Image=FreeImage_ConvertFromRawBits(src,128,128,128,8,0,0,0,false);
//	FreeImage_Save(FIF_PNG,Image,"wdtest.png",0);
//	FreeImage_Unload(Image);
//	use FreeImage to save color image succeed.
//   FIBITMAP* bitmap=FreeImage_Allocate(16,16,3);
//	BYTE *src=new BYTE[1024*720*3];
//	for(int i=0;i<1024*720;i++){
//		src[i*3]=i;
//		src[i*3+1]=i;
//		src[i*3+2]=200;
//	}
//	FIBITMAP* Image=FreeImage_ConvertFromRawBits(src,1024,720,1024*3,8*3,0,0,0,false);
//	FreeImage_Save(FIF_BMP,Image,"saveimg2.bmp");
//	FreeImage_Unload(Image);

	std::cout<<FreeImage_GetVersion()<<std::endl;

   clReleaseKernel(kernel);
   clReleaseProgram(program);
   clReleaseCommandQueue(cmdQueue);
   clReleaseMemObject(bufInputImage);
   clReleaseMemObject(bufOutputImage);
   clReleaseContext(context);
   free(Outputimg);
   free(programSource);

   return 0;
}
cl部分我没有动。

结果保存出来了:

果然是FreeImage库的使用那里的问题,用opencv替代就好了。

大神指点后,我终于知道怎么用FreeImage保存灰度图了:http://blog.csdn.net/bob_dong/article/details/64131352  大神很厉害!

/**
 * 把缓冲区中的数据保存为灰度图像文件
 */
int store_image(uint8_t *buffer, const char *image_name)
{
	int i, j, ret = 0;

	// 创建新的位图对象
	FIBITMAP *bitmap = FreeImage_Allocate(g_width, g_height, 32);
	if (bitmap == NULL) {
		printf("alloc bitmap fail\n");
		return EXIT_FAILURE;
	}

	uint8_t *bits = FreeImage_GetBits(bitmap);
	for (i = 0; i < g_width * g_height; i++) {
		for (j = 0; j < 3; j++)
		{
			bits[i*4+j] = buffer[i];
		}
		bits[i*4+3]=255;
	}

	FreeImage_Save(g_format, bitmap, image_name);
	FreeImage_Unload(bitmap);

	return ret;
}

原来FreeImage的灰度图也是32位啊也需要跟彩图一样的大小width*height*32,RGB三个通道都是同样的值,相当于将opencv里的单通道的值复制到这三个通道,然后A这个就直接255.。我原来以为它的灰度图跟opencv一样width*height*8就好了 难怪一直异常。






  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

元气少女缘结神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值