no message
parent
cd72125f29
commit
7f6d765d28
|
@ -0,0 +1,162 @@
|
|||
#include <windows.h>
|
||||
#include "cvhelper.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
/*
|
||||
* 将一幅RGB图像转换YCrCb图像,并得到三个分离的通道。
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 将Y、Cr、Cb三个分离的通道合并为YCrCb图像,再转换为RGB图像。
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -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
|
Loading…
Reference in New Issue