/**
* @file miscellaneous.hpp
* @author 闹闹
* @brief 杂项内容,不归类
* @details 为天地立心,为生民立命,为往圣继绝学,为万世开太平。
* @version 1.0.0.1
* @date 2022年6月29日09:28:08
* @copyright Copyright (c) 2050
*
**********************************************************************************
* @par 修改日志:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td> <td>1.0.0.2 <td>naonao <td>
* </table>
*
***********************************************************************************
* @par 修改日志:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2021年1月11日15:27:52<td>1.0.0.3 <td>naonao <td>
* </table>
*
***********************************************************************************
* @par 修改日志:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td> <td>1.0.0.4 <td>naonao <td>
* </table>
*
***/
#pragma once
#ifndef __MISCELLANEOUS_H__
#define __MISCELLANEOUS_H__
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
//标准库
#include <time.h>
#include <iostream>
#include <map>
//第三方库
#include "opencv2/opencv.hpp"
#define CV_VERSION_ID CVAUX_STR(CV_MAJOR_VERSION) \
CVAUX_STR(CV_MINOR_VERSION) \
CVAUX_STR(CV_SUBMINOR_VERSION)
#ifdef _DEBUG
#define cvLIB(name) "opencv_" name CV_VERSION_ID "d"
#else
#define cvLIB(name) "opencv_" name CV_VERSION_ID
#endif
//链接库
//#pragma comment( lib, cvLIB("img_hash") )
#pragma comment( lib, cvLIB("world") )
namespace nao {
namespace algorithm{
/**
* @brief gamma变换
* @param img
* @param gamma
* @param n_c
* @return
*/
cv::Mat gamma_trans(const cv::Mat& img, double gamma, int n_c = 1) {
cv::Mat img_gamma(img.size(), CV_32FC1);
for (int i = 0; i < img.rows; i++) {
for (int j = 0; j < img.cols; j++) {
img_gamma.at<float>(i, j) = n_c * pow(img.at<uchar>(i, j), gamma);
}
}
cv::normalize(img_gamma, img_gamma, 0, 255, cv::NormTypes::NORM_MINMAX);
cv::convertScaleAbs(img_gamma, img_gamma); //将CV_32F的图像转成CV_8U的
return img_gamma;
}
/**
* @brief
* @param img
* @param sin 黑场阈值
* @param hin 白场阈值
* @param mt 灰度调节
* @param sout 输出黑场阈值
* @param hout 输出白场阈值
* @return
* @see https://blog.youkuaiyun.com/youcans/article/details/125373625
*/
cv::Mat gray_stairs(const cv::Mat& img, double sin = 0.0, double hin = 255.0, double mt = 1.0, double sout = 0.0, double hout = 255.0) {
double Sin = std::min(std::max(sin, 0.0), hin - 2); //Sin, 黑场阈值, 0 <= Sin < Hin
double Hin = std::min(hin, 255.0); //Hin, 白场阈值, Sin<Hin<=255
double Mt = std::min(std::max(mt, 0.01), 9.99); // Mt, 灰场调节值, 0.01~9.99
double Sout = std::min(std::max(sout, 0.0), hout - 2); // Sout, 输出黑场阈值, 0<=Sout<Hout
double Hout = std::min(hout, 255.0); //Hout, 输出白场阈值, Sout<Hout<=255
double difin = Hin - Sin;
double difout = Hout - Sout;
uchar lutData[256];
for (int i = 0; i < 256; i++) {
double v1 = std::min(std::max(255 * (i - Sin) / difin, 0.0), 255.0); //输入动态线性拉伸
double v2 = 255 * std::pow(v1 / 255.0, 1.0 / Mt); //灰场伽马调节
lutData[i] = (int)std::min(std::max(Sout + difout * v2 / 255, 0.0), 255.0); //# 输出线性拉伸
}
cv::Mat lut(1, 256, CV_8UC1, lutData);
cv::Mat dst;
cv::LUT(img, lut, dst);
return dst;
}
/**
* @brief 形态学处理种类
*
* @details
*/
enum class PhologyType
{
FS = 1, ///<只有当卷积核对应的元素全为1时,其值才为1,否则均为0。
PZ = 2, ///<当卷积核对应的元素只要有一个为1时,其值便为1,否则为0。
K = 3, ///<对腐蚀后的图像,进行膨胀处理,可以去除噪声,并保持原有形状。
B = 4, ///<闭运算是先膨胀,后腐蚀,它有助于关闭前景物体内部的小孔,或物体上的小黑点。
TD = 5, ///<梯度运算即为膨胀图像减去腐蚀图像从而得到轮廓图像。
DM = 6, ///<礼帽运算即为原始图像减去开运算的图像,得到其中的噪声图像
HM = 7 ///<黑帽运算即为闭运算图像减去原始图像,得到图片内部的小孔,或前景色中的小黑点
}; // enum type
/**
* @brief 形态学核的种类
*
* @details
*/
enum KernelShape
{
JUXING = cv::MorphShapes::MORPH_RECT,
SHIZI = cv::MorphShapes::MORPH_CROSS,
TUOYUAN = cv::MorphShapes::MORPH_ELLIPSE
}; // enum shape
/**
* @brief 形态学运算
* @param src 原图
* @param size 大小
* @param type 种类
* @param shape 默认矩形
* @return cv:: Mat
*
* @details
*/
cv:: Mat morphology(const cv::Mat src, cv::Size size, PhologyType type, KernelShape shape = KernelShape::JUXING)
{
cv:: Mat element = cv:: getStructuringElement(shape, size);
cv:: Mat dst;
switch (type)
{
case PhologyType::FS :
cv:: erode(src, dst, element);
break;
case PhologyType::PZ :
cv:: dilate(src, dst, element);
break;
case PhologyType::K :
cv:: morphologyEx(src, dst, cv::MORPH_OPEN, element);
break;
case PhologyType::B :
cv:: morphologyEx(src, dst, cv::MORPH_CLOSE, element);
break;
case PhologyType::TD :
cv:: morphologyEx(src, dst, cv::MORPH_GRADIENT, element);
break;
case PhologyType::DM :
cv:: morphologyEx(src, dst, cv::MORPH_TOPHAT, element);
break;
case PhologyType::HM :
cv:: morphologyEx(src, dst, cv::MORPH_BLACKHAT, element);
break;
default:
break;
}
return dst;
}
void get_rect_img(const cv::Mat& img, std::vector<cv::Point2i>& vecPt, cv::Mat& grayimg) {
if (vecPt.size()<3) {
grayimg = img.clone();
return;
}
//构建凸包
std::vector<cv::Point2i> hull;
cv::convexHull(vecPt, hull);
//构建mask
cv::Mat mask = cv::Mat::zeros(cv::Size(img.cols, img.rows), img.type());
std::vector<std::vector<cv::Point2i>> contour;
contour.emplace_back(hull);
cv::drawContours(mask, contour, 0, cv::Scalar(255, 255, 255), cv::FILLED);
//输出
cv::Mat ret;
img.copyTo(ret, mask);
grayimg = ret.clone();
}
}//namespace algorithm
}// namespace nao
#endif //__MISCELLANEOUS_H__
/*----------------------------------------------------------------------------- (C) COPYRIGHT LEI *****END OF FILE------------------------------------------------------------------------------*/
杂项代码未分类
最新推荐文章于 2025-08-05 19:25:04 发布