图像处理基本方法-C语言调用opencv生成纯色BMP文件
之前使用过c语言实现过成纯色BMP文件的功能。
这次使用c调用opencv的库函数,生成纯色bmp文件。
主要调用opencv的cvRectangle函数实现。
函数原型
void cvRectangle(CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int line_type=8, int shift=0 )
参数介绍
CvArr* img:IplImage格式,用cvCreateImage创建。
CvPoint pt1:绘制矩形的起始顶点。
CvPoint pt2:绘制矩形的对角线上的另一个顶点。
CvScalar color:线条颜色 (RGB) 或亮度(灰度图像 )(grayscale image)。
int thickness=1:组成矩形的线条的粗细程度。取负值时(如 CV_FILLED)函数绘制填充了色彩的矩形。
int line_type=8:线条的类型。见cvLine的描述
int shift=0:坐标点的小数点位数。
关键参数thickness设置为CV_FILLED表示填充矩形。
函数调用
cvRectangle(testImage,
cvPoint(0,0),
cvPoint(iWidth,iHeight),
cvScalar(u8B,u8G,u8R,0),
CV_FILLED);
代码实现
代码主要使用之前的c语言生成纯色BMP文件中的代码,只把生成纯色图片数据并存文件的函数接口,更换成opencv的方式实现。
具体程序实现如下:
/*******************************************************
* file:testBmpCv.c
* date:2021-05-30
* version:1.0.0.1
* author:www
* description: create bmp file
*******************************************************/
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <sys/time.h>
#include <string.h>
// opencv
#include "opencv2/highgui/highgui.hpp"
#define PRINT_CTRL 1
typedef unsigned char WORD8; /* 8位无符号整型 */
typedef unsigned short WORD16; /* 16位无符号整型 */
typedef unsigned int WORD32; /* 32位无符号整型 */
typedef unsigned char BYTE; /* 8位无符号整型 */
typedef signed int INT; /* 32位有符号整型 */
typedef signed char CHAR; /* 8位有符号字符型 */
typedef signed long LONG; /* 32位有符号长整型 */
typedef unsigned long uLONG; /* 32位无符号长整型 */
typedef signed short SHORT; /* 16位有符号整型 */
typedef void *LPVOID; /* 空类型 */
typedef unsigned char BOOLEAN; /* 布尔类型 */
#pragma pack(push)
#pragma pack(1)
typedef struct INFOHEADER
{
WORD32 biSize;
WORD32 biWidth;
WORD32 biHeight;
WORD16 biPlanes;
WORD16 biBitCount;
WORD32 biCompression;
WORD32 biSizeImage;
WORD32 biXPelsPerMeter;
WORD32 biYPelsPerMeter;
WORD32 biClrUsed;
WORD32 biClrImportant;
}BITMAPINFOHEADER;
typedef struct tagBITMAPFILEHEADER
{
WORD16 bfType;
WORD32 bfSize;
WORD16 bfReserved1;
WORD16 bfReserved2;
WORD32 bfOffBits;
} BITMAPFILEHEADER;
#pragma pack(pop)
/*
u8PicNameOut 输出的bmp路径及名字,返回值,如果pcPtnBuf为NULL时,则返回bmp文件
iWidth 要转换的bmp图片宽度,1-4096
iHeight 要转换的bmp图片高度,1-4096
pcPtnBuf[] 输入的图片buffer地址,可为NULL,为NULL时生成bmp图片,返回的名称在u8PicNameOut
int iBmpBit 要转换的bit数,3-表示输出8bit的bmp,即RGB, 6-表示输出16bit的bmp,RRGGBB
BYTE u8R
BYTE u8G
BYTE u8B
*/
int generateBmpFunc(char u8PicNameOut[], int iWidth, int iHeight,BYTE pcPtnBuf[],int iBmpBit, BYTE u8R, BYTE u8G, BYTE u8B)
{
CvSize size = cvSize(iWidth, iHeight); //(400, 400);
IplImage * testImage = cvCreateImage(size, IPL_DEPTH_8U, 3);
// opencv
#if 1
// 画矩形 ok
printf("cvRectangle before BGR=%d,%d,%d\r\n",u8B,u8G,u8R);
cvRectangle(testImage,
cvPoint(0,0),
cvPoint(iWidth,iHeight),
cvScalar(u8B,u8G,u8R,0),
CV_FILLED);
printf("cvRectangle out\r\n");
#endif
cvSaveImage(u8PicNameOut, testImage,0);
cvReleaseImage(&testImage);
}
//主函数
int main(int argc, char * * argv)
{
char u8PicNameRead[64] = {0};
char u8PicNameOut[64] = {0};
int iBmpBit = 3;
int iBmpBitTmp = 0;
struct timeval tStartTime;
struct timeval tEndTime;
int isecond = 0;
int iusecond = 0;
int iWidth = 0;
int iHeigth = 0;
BYTE u8R = 0;
BYTE u8G = 0;
BYTE u8B = 0;
if(argc < 8)
{
printf("please input like this:\r\n");
printf("./testBmpCv.bin test.bmp 3 1920 1080 255 255 255 \r\n");
printf("test.bmp --------------- output file \r\n");
printf("3 --------------- 3-RGB 3 bytes \r\n");
printf("1920 --------------- width\r\n");
printf("1080 ---------------- heigth \r\n");
printf("255 ---------------- B \r\n");
printf("255 ---------------- G \r\n");
printf("255 ---------------- R \r\n");
return -1;
}
printf("argv[1]=%s\r\n",argv[1]);
printf("argv[2]=%s,%d\r\n",argv[2],atoi(argv[2]));
sprintf(u8PicNameRead,"%s",argv[1]);
sprintf(u8PicNameOut,"%s",argv[1]);
printf("u8PicNameRead=%s\r\n",u8PicNameRead);
iBmpBitTmp = atoi(argv[2]);
if(iBmpBitTmp == 3 || iBmpBitTmp ==6)
{
iBmpBit = iBmpBitTmp;
}
iWidth = atoi(argv[3]);
iHeigth = atoi(argv[4]);
u8R = atoi(argv[5]);
u8G = atoi(argv[6]);
u8B = atoi(argv[7]);
printf("iWidth = %d\r\n",iWidth);
printf("iHeigth = %d\r\n",iHeigth);
printf("u8R = %d\r\n",u8R);
printf("u8G = %d\r\n",u8G);
printf("u8B = %d\r\n",u8B);
gettimeofday(&tStartTime, NULL);
//printf("tStartTime time.tv_sec = %d, time.tv_usec = %d.\r\n", tStartTime.tv_sec, tStartTime.tv_usec);
generateBmpFunc(u8PicNameOut,iWidth,iHeigth,NULL,iBmpBit,u8R,u8G,u8B);
//*
gettimeofday(&tEndTime, NULL);
if(tEndTime.tv_sec >= tStartTime.tv_sec)
{
isecond = tEndTime.tv_sec-tStartTime.tv_sec;
}
if(tEndTime.tv_usec >= tStartTime.tv_usec)
{
iusecond = tEndTime.tv_usec-tStartTime.tv_usec;
}
else
{
isecond--;
iusecond = tEndTime.tv_usec-tStartTime.tv_usec + 1000000;
}
//printf("tEndTime time.tv_sec = %d, time.tv_usec = %d.\r\n", tEndTime.tv_sec, tEndTime.tv_usec);
printf("gernerateBmpFunc use time tv_sec=%ds, ms=%d, tv_usec=%dus\r\n",isecond,iusecond/1000,iusecond);
//*/
printf("u8PicNameOut=%s\r\n",u8PicNameOut);
return 0;
}
makefile文件
#############################################################################
CROSS_COMPILE =
CC = $(CROSS_COMPILE)gcc -g
CPP = $(CROSS_COMPILE)g++
CXX = $(CROSS_COMPILE)g++
AR = $(CROSS_COMPILE)ar
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
NM = $(CROSS_COMPILE)nm
RM = rm
MAKE = @make
MKDIR = mkdir -p
COPY = @copy
CD = @cd
ECHO = @echo
ZIP = @gzip
PWD_DIR := $(shell pwd)
#OPENCV_BASE_DIR := $(PWD_DIR)/../output/
OPENCV_BASE_DIR := /usr/local/
OPENCV_DIR := -I$(OPENCV_BASE_DIR)/include
OPENCV1_DIR := -I$(OPENCV_BASE_DIR)/include/opencv
OPENCV2_DIR := -I$(OPENCV_BASE_DIR)/include/opencv2
OPENCV_LIB_DIR := -L$(OPENCV_BASE_DIR)lib/
OPENCV_LIB_DIR2 := -L$(OPENCV_BASE_DIR)lib/
OPENCV_LIBS := $(OPENCV_LIB_DIR)libopencv_highgui.a\
$(OPENCV_LIB_DIR)libopencv_core.a\
$(OPENCV_LIB_DIR)libopencv_imgproc.a\
$(OPENCV_LIB_DIR)libopencv_objdetect.a
INC_FLAGS := $(OPENCV_DIR) $(OPENCV1_DIR) $(OPENCV2_DIR)
SRC := $(wildcard *.c)
OBJ := $(SRC:%.c=%.o)
#TARGET := $(OBJ:%.o=%)
TARGET := testBmpCv.bin
.PHONY : clean all
all : testBmpCv.bin
testBmpCv.bin:
$(CXX) testBmpCv.c $(INC_FLAGS) $(OPENCV_LIB_DIR2) -fPIC -lpthread -lz -lopencv_highgui -lopencv_core -lopencv_imgproc -lopencv_objdetect -o $(TARGET) $(OBJS) $(LIBS)
clean:
rm -f $(OBJS) $(TARGET)
编译程序
编译命令如下
make
执行完上述命令之后,会生成testBmpCv.bin文件,后面执行程序时需要该文件。
执行程序
使用如下命令执行程序,可产生bmp文件。
testBmpCv.bin test.bmp 3 1920 1080 255 0 0
执行上述命令,由于需要写入大量数据,所以耗时较长。
执行完成之后,会生成bmp文件。
需要修改分辨率和颜色的话,可以修改输入的宽高和红绿蓝参数即可。
参考资料
https://blog.csdn.net/jack8126/article/details/116331956
https://blog.csdn.net/jack8126/article/details/117408043