no message

master
zcy 2022-05-18 02:28:56 +08:00
parent cd72125f29
commit 7f6d765d28
2 changed files with 179 additions and 0 deletions

View File

@ -0,0 +1,162 @@
#include <windows.h>
#include "cvhelper.h"
#include <iostream>
#include <fstream>
/*
* RGBYCrCb
*/
void TransferRGB2YCrCb(cv::Mat &input, std::vector<cv::Mat> &chls)
{
//YCrCb色彩空间Y为颜色的亮度luma成分、而CB和CR则为蓝色和红色的浓度偏移量成分。
//只有Y成分的图基本等同于彩色图像的灰度图。
cv::cvtColor(input, input, cv::COLOR_BGR2YCrCb);
cv::split(input, chls);
}
/*
* YCrCbYCrCbRGB
*/
void MergeYCrCb2RGB(cv::Mat &output, std::vector<cv::Mat> &chls)
{
cv::merge(chls, output);
cv::cvtColor(output, output, cv::COLOR_YCrCb2BGR);
}
/*
*CLAHE.
*@ClipLimit:ClipLimit,*
*ClipLimit
*,
*@TilesGridSize:// 将图像分为TilesGridSize*TilesGridSize大小的方块.。滑动窗口大小为TilesGridSize*TilesGridSize
*/
cv::Mat clahe_deal(cv::Mat &src, double ClipLimit = 40.0, int TilesGridSize = 8)
{
cv::Mat ycrcb = src.clone();
std::vector<cv::Mat> channels;
// TransferRGB2YCrCb(ycrcb, channels);
// cv::Mat clahe_img;
// //opencv源码中原型 createCLAHE(double clipLimit = 40.0, Size tileGridSize = Size(8, 8));
// cv::Ptr<cv::CLAHE> clahe = cv::createCLAHE();
// clahe->setClipLimit(ClipLimit);
// clahe->setTilesGridSize(Size(TilesGridSize, TilesGridSize));
// clahe->apply(channels[0], clahe_img);
// channels[0].release();
// clahe_img.copyTo(channels[0]);
// MergeYCrCb2RGB(ycrcb, channels);
// return ycrcb;
return ycrcb;
}
//将mat数组转换为二进制255用1表示0用0表示
int Mat2Binary(const cv::Mat img, int line_byte, char* data)
{
int width = img.cols;
int height = img.rows;
size_t line_size = line_byte * 8;
size_t bit_size = line_size * height;
char* p = data; int offset, v; unsigned char temp;
for (int row = height - 1; row >= 0; row--)
{
for (int col = 0; col < width; col++)
{
offset = col % 8;
//v = img.data[row * width + col];
v = img.at<uchar>(row, col);
temp = 1;
temp = temp << (8 - offset - 1);
if (v == 255)
{
*(p + col / 8) |= temp;
}
else
{
temp = ~temp;
*(p + col / 8) &= temp;
}
}
//注释掉一下代码列数否则不能被4整除的图像最后4列会出现黑边
/* for (int j = width / 8; j < line_byte + 1; j++) {
p[j] = 0;
} */
p = p + line_byte;
}
return 0;
}
//将Mat图像保存为1位bmp图
int Save1BitImage(const cv::Mat img, std::string dst)
{
int width = img.cols;
int height = img.rows;
const int biBitCount = 1;
//待存储图像数据每行字节数为4的倍数计算位图每行占多少个字节
//int line_byte = (width * biBitCount >> 3 + 3) / 4 * 4;
int line_byte = (width * biBitCount / 8 + 5) / 4 * 4;//+3改为+5,否则无法向上对齐,造成崩溃
char* p_data = (char*)malloc(line_byte * height + 1);//后面加1否则会报heap错误
//memset(p_data, 0x01, line_byte * height+1);
//将mat数组转换为二进制255用1表示0用0表示
Mat2Binary(img, line_byte, p_data);
//bmp位图颜色表大小以字节为单位灰度图像颜色表为256*4字节彩色图像颜色表大小为0,二值图为2*4
int color_type_num = 2;
int colorTablesize = color_type_num * sizeof(RGBQUAD);
RGBQUAD* pColorTable = new RGBQUAD[color_type_num];
for (int i = 0; i < color_type_num; i++) {
pColorTable[i].rgbBlue = i * 255;
pColorTable[i].rgbRed = i * 255;
pColorTable[i].rgbGreen = i * 255;
pColorTable[i].rgbReserved = 0;
}
//申请位图文件头结构变量,填写文件头信息
BITMAPFILEHEADER fileHead;
fileHead.bfType = 0x4D42; //bmp类型
fileHead.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + colorTablesize + line_byte * height; //bfSize是图像文件4个组成部分之和,图文件的大小,以字节为单位
fileHead.bfReserved1 = 0;//位图文件保留字必须为0
fileHead.bfReserved2 = 0;
fileHead.bfOffBits = 54 + colorTablesize; //bfOffBits是图像文件前3个部分所需空间之和,位图数据的起始位置
//申请位图信息头结构变量,填写信息头信息
BITMAPINFOHEADER head;
head.biBitCount = biBitCount;//每个像素所需的位数必须是1双色29-30字节4(16色8(256色16(高彩色)或24真彩色之一
head.biCompression = BI_RGB; //位图压缩类型,必须为BI_RGB否则图片打开会有错误
head.biHeight = height;//位图的高度,以像素为单位
head.biWidth = width;
//head.biSize = 40;
head.biSize = sizeof(BITMAPINFOHEADER);//本结构所占用字节数
head.biSizeImage = line_byte * height;//位图的大小(其中包含了为了补齐行数是4的倍数而添加的空字节)
head.biPlanes = 1;//目标设备的级别必须为1
head.biXPelsPerMeter = 23622;//位图水平分辨率每米像素数分辨率设为600
head.biYPelsPerMeter = 23622;//位图垂直分辨率,每米像素数
head.biClrImportant = 0;//位图显示过程中重要的颜色数
head.biClrUsed = 0;//位图实际使用的颜色表中的颜色数
std::ofstream fp(dst.c_str(), std::ios::binary | std::ios::out);
if (!fp.is_open()) {
return -1;
}
fp.write((char*)&fileHead, sizeof(BITMAPFILEHEADER)); //写文件头进文件
//写位图信息头进内存
fp.write((char*)&head, sizeof(BITMAPINFOHEADER));
//颜色表,写入文件
fp.write((char*)pColorTable, sizeof(RGBQUAD) * color_type_num);
//写位图数据进文件pBmpBuf
fp.write((char*)p_data, height * line_byte);
fp.close();
delete[]pColorTable;
delete[]p_data;
return 0;
}

View File

@ -0,0 +1,17 @@
#ifndef CVHELPER_H
#define CVHELPER_H
// 常见opencv 图像操作的一层wrap
#include "opencv2/opencv.hpp"
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
void TransferRGB2YCrCb(cv::Mat &input, std::vector<cv::Mat> &chls);
void MergeYCrCb2RGB(cv::Mat &output, std::vector<cv::Mat> &chls);
cv::Mat clahe_deal(cv::Mat &src, double ClipLimit , int TilesGridSize );
int Save1BitImage(const cv::Mat img, std::string dst);
int Mat2Binary(const cv::Mat img, int line_byte, char* data);
#endif // CVHELPER_H