图像处理之Retinex算法(C++)

news2024/10/5 17:54:05

图像处理之Retinex算法(C++)


文章目录

  • 图像处理之Retinex算法(C++)
  • 前言
  • 一、单尺度Retinex(SSR)
    • 1.原理
    • 2.代码实现
    • 3.结果展示
  • 二、多尺度Retinex(MSR)
    • 1.原理
    • 2.代码实现
    • 3.结果展示
  • 三、带色彩恢复的多尺度Retinex(MSRCR)
    • 1.原理
    • 2.代码实现
    • 3.结果展示
  • 总结


前言

Retinex 理论的基本思想就是光照强度决定了原始图像中所有像素点的动态范围大小,而原始图像的固有属性则是由物体自身的反射系数决定,即假设反射图像和光照图像相乘为原始图像。所以 Retinex 的思路即是去除光照的影响,保留住物体的固有属性。
Retinex模型示意图
如图所示,假设观察者处成像的图像为I(x,y),可以通过下式表达:
成像公式1
参数解释:
I(x,y)–源图像;
L(x,y)–表示光照分量;
R(x,y)–表示物体本身固有性质的反射分量。
对公式两端取对数,公式为:
公式2
公式3
上式即为Retinex理论处理的基本过程。
Retinex算法处理的基本过程如下:
Retinex理论处理的基本过程
流程图解读:图像I(x,y)经过Log变换转换成i(x,y),然后对图像I(x,y)进行亮度图像估计,在对估计的亮度分量进行Log变换得到l(x,y),二者相减得到物体反射分量的Log变换r(x,y),再进行Log变换的反变换Exp,即得到R(x,y)。此处亮度图像估计即通过高斯滤波或者引导滤波对图像滤波
参考资料:Retinex理论


一、单尺度Retinex(SSR)

1.原理

单尺度 Retinex 算法的处理过程非常拟合人眼的视觉成像过程,该算法的基本思路是:先构建高斯环绕函数,然后利用高斯环绕函数分别对图像的三个色彩通道 (R 、G 和 B) 进行滤波,则滤波后的图像就是我们所估计的光照分量,接着再在对数域中对原始图像和光照分量进行相减得到反射分量作为输出结果图像。该算法能压缩图像的动态范围、一定程度上的保持图像的颜色和细节的增强。改进:将高斯环绕函数对三个色彩通道滤波,改为使用引导滤波对三个彩色通道滤波。
公式3
参数解释:
Ii(x,y)–原始图像;
Li(x,y)–表示光照分量;
Ri(x,y)–表示物体本身固有性质的反射分量;
G(x,y)–高斯环绕函数;
Ii(x,y)G(x,y)–对原始图像使用高斯核进行卷积运算。
SSR算法中标准差σ一般取80-100。

2.代码实现

#include <iostream>
#include <opencv.hpp>
using namespace std;

/*
* @param cv::Mat src	输入图像
* @param cv::Mat& dst	输出图像
* @param double sigma   高斯核的标准差
* @breif 单尺度Retinex图像处理
*/
cv::Mat single_scale_retinex(const cv::Mat& src,double sigma)
{
	cv::Mat gaussImg, log_src(src.size(),CV_32F), log_gaussImg(src.size(), CV_32F);
	cv::Mat difference(src.size(), CV_32F);
	cv::Mat dst(src.size(), CV_32F);

	// 对输入图像进行高斯模糊处理
	cv::GaussianBlur(src, gaussImg, cv::Size(0,0), sigma);

	// 对模糊后的图像和原图像分别进行对数运算,得到两个对数图像
	// 差分操作前确保两个矩阵类型和尺寸相同
	// 对差分后的图像进行指数运算
	gaussImg.convertTo(gaussImg, CV_32F);
	for(int i=0;i<gaussImg.rows;i++)
		for (int j = 0; j < gaussImg.cols; j++)
		{
			log_gaussImg.at<float>(i, j) = log(gaussImg.at<float>(i, j) + 1);
			log_src.at<float>(i, j) = log(src.at<uchar>(i, j) + 1);
			difference.at<float>(i, j) = log_src.at<float>(i, j) - log_gaussImg.at<float>(i, j);
			//dst.at<float>(i, j) = exp(difference.at<float>(i, j));
		}
	// 归一化到0-255范围内(疑问:此处对差分图像归一化反而图像显得正常,参考https://blog.csdn.net/TmacDu/article/details/103499795博主也是这样实现)
	cv::normalize(difference, dst, 0, 255, cv::NORM_MINMAX, CV_8U);

	return dst;
}

/*
* @param cv::Mat src	输入图像
* @param cv::Mat& dst	输出图像
* @param double sigma   高斯核的标准差
* @breif 单尺度Retinex图像处理
*/
void retinex_process(const cv::Mat& src, cv::Mat& dst, double sigma)
{
	std::vector<cv::Mat> channels;
	std::vector<cv::Mat> channels_dst;
	cv::split(src, channels);
	for (int i = 0; i < channels.size(); i++)
	{
		channels_dst.push_back(single_scale_retinex(channels[i], sigma));
	}
	cv::merge(channels_dst, dst);
}

int main()
{
	// 读取图片
	string filepath = "F://work_study//algorithm_demo//retinex_test1.jpg";
	cv::Mat src = cv::imread(filepath);
	if (src.empty())
	{
		return -1;
	}
	cv::Mat dst(src.size(),CV_8UC3,cv::Scalar(0,0,0));

	//执行单尺度的Retinex算法
	retinex_process(src, dst,80);

	cv::imshow("dst.jpg", dst);
	cv::waitKey(0);
	return 0;
}

3.结果展示

原图
结果

二、多尺度Retinex(MSR)

1.原理

SSR算法在动态范围压缩和色调恢复的两种效果中,只能以牺牲一种功能为代价来改进另一个,因此Jobson等一批研究者们针对单尺度Retinex模型中存在的不足,提出了将不同尺度下的增强结果线性地组合在一起,充分将局部信息和整体信息考虑进去的多尺度Retinex算法。这种算法的主要思想就是结合几种不同的尺度的中心围绕函数通过加权平均以后来估计光照分量。MSR算法可以产生同时拥有良好动态范围压缩、色彩稳定性以及良好色调恢复的单一输出图像。MSR算法的公式为:
MSR
参数解释:
N–表示尺度的个数,即高斯滤波的标准差的个数,一般将N的取值为3,用三个不同尺度的高斯滤波器对原始图像进行滤波,尺度的比例建议为15:80:250。
wk–经过实验验证,发现w1=w2=w3=1/3时,适用于大量的低照度图像,运算简单。
Fk(x,y)–在第k个尺度上的高斯滤波函数。

参考资料:MSR资料

2.代码实现

#include <iostream>
#include <opencv.hpp>
using namespace std;

/*
* @param cv::Mat src	输入图像
* @param cv::Mat& dst	输出图像
* @param double sigma   高斯核的标准差
* @breif 单尺度Retinex图像处理
*/
cv::Mat single_scale_retinex(const cv::Mat& src,double sigma)
{
	cv::Mat gaussImg, log_src(src.size(),CV_32F), log_gaussImg(src.size(), CV_32F);
	cv::Mat difference(src.size(), CV_32F);
	cv::Mat dst(src.size(), CV_32F);

	// 对输入图像进行高斯模糊处理
	cv::GaussianBlur(src, gaussImg, cv::Size(0,0), sigma);

	// 对模糊后的图像和原图像分别进行对数运算,得到两个对数图像
	// 差分操作前确保两个矩阵类型和尺寸相同
	// 对差分后的图像进行指数运算
	gaussImg.convertTo(gaussImg, CV_32F);
	for(int i=0;i<gaussImg.rows;i++)
		for (int j = 0; j < gaussImg.cols; j++)
		{
			log_gaussImg.at<float>(i, j) = log(gaussImg.at<float>(i, j) + 1);
			log_src.at<float>(i, j) = log(src.at<uchar>(i, j) + 1);
			difference.at<float>(i, j) = log_src.at<float>(i, j) - log_gaussImg.at<float>(i, j);
			//dst.at<float>(i, j) = exp(difference.at<float>(i, j));
		}
	// 归一化到0-255范围内(疑问:此处对差分图像归一化反而图像显得正常,参考https://blog.csdn.net/TmacDu/article/details/103499795博主也是这样实现)
	cv::normalize(difference, dst, 0, 255, cv::NORM_MINMAX, CV_8U);

	return dst;
}

/*
* @param cv::Mat src	输入图像
* @param cv::Mat& dst	输出图像
* @param double sigma   高斯核的标准差
* @breif 单尺度Retinex图像处理
*/
void retinex_process(const cv::Mat& src, cv::Mat& dst, double sigma)
{
	std::vector<cv::Mat> channels;
	std::vector<cv::Mat> channels_dst;
	cv::split(src, channels);
	for (int i = 0; i < channels.size(); i++)
	{
		channels_dst.push_back(single_scale_retinex(channels[i], sigma));
	}
	cv::merge(channels_dst, dst);
}

/*
* @param cv::Mat src	输入图像
* @param cv::Mat& dst	输出图像
* @param std::vector<double> sigma   高斯核的标准差
* @param std::vector<double> w   权重系数
* @breif 多尺度Retinex图像处理
*/
void multi_retinex_process(const cv::Mat& src, cv::Mat& dst, std::vector<double>& sigma, std::vector<double>& w)
{
	std::vector<cv::Mat> temp(sigma.size());
	for (int i = 0; i < sigma.size(); i++)
	{
		retinex_process(src,temp[i],sigma[i]);
	}
	for (int i = 0; i < w.size(); i++)
	{
		dst += w[i] * temp[i];
	}
}


int main()
{
	// 读取图片
	string filepath = "F://work_study//algorithm_demo//retinex_test3.jpg";
	cv::Mat src = cv::imread(filepath);
	if (src.empty())
	{
		return -1;
	}
	cv::Mat dst(src.size(),CV_8UC3,cv::Scalar(0,0,0));

	//高斯滤波器的尺度
	std::vector<double> sigma={15,80,250};
	//各个尺度下的SSR的权重系数
	std::vector<double> w(3, 1 / 3.0);

	//执行多尺度的Retinex算法
	multi_retinex_process(src, dst,sigma,w);

	cv::imwrite("dst.jpg", dst);
	cv::waitKey(0);
	return 0;
}

3.结果展示

MSR结果

三、带色彩恢复的多尺度Retinex(MSRCR)

1.原理

在上图中,我们可以看出无论是单尺度还是多尺度Retinex图像增强后都会发生图像色彩失真,原因是R、G、B三通道的像素值比例发生改变,针对这个现象,Jobson和Rahman等人又一次提出带颜色恢复的多尺度 Retinex(MSRCR)。该算法可以将 MSR 得到的结果按照一定的比例进行调整以求恢复原来的比例数值,具体是通过引入了颜色恢复因子 C ,其公式如下:颜色恢复因子公式
参数解释:
β–增益常数,经验参数为46。
α–调节因子,经验参数为125。
Ci(x,y)–第i个彩色通道的色彩恢复函数(CRF),用来调节三个通道颜色在图像中所占的比例。
MSRCR可以提供必要的颜色恢复,从而把相对较暗区域而无法观察到的信息图像细节展现出来,消除了MSR输出中明显的颜色失真和灰色区域。可以为大多数图像提供良好的效果。
MSRCR公式
参数解释:
t–偏移量系数;
G–增益系数;

2.代码实现

#include <iostream>
#include <opencv.hpp>
using namespace std;
using namespace cv;
/*
* @param cv::Mat src	输入图像
* @param cv::Mat& dst	输出图像
* @param double sigma   高斯核的标准差
* @breif 单尺度Retinex图像处理
*/
cv::Mat single_scale_retinex(const cv::Mat& src, double sigma)
{
	cv::Mat gaussImg, log_src(src.size(), CV_32F), log_gaussImg(src.size(), CV_32F);
	cv::Mat difference(src.size(), CV_32F);
	cv::Mat dst(src.size(), CV_32F);

	// 对输入图像进行高斯模糊处理
	cv::GaussianBlur(src, gaussImg, cv::Size(0, 0), sigma);

	// 对模糊后的图像和原图像分别进行对数运算,得到两个对数图像
	// 差分操作前确保两个矩阵类型和尺寸相同
	// 对差分后的图像进行指数运算
	gaussImg.convertTo(gaussImg, CV_32F);
	for (int i = 0; i < gaussImg.rows; i++)
		for (int j = 0; j < gaussImg.cols; j++)
		{
			log_gaussImg.at<float>(i, j) = log(gaussImg.at<float>(i, j) + 1);
			log_src.at<float>(i, j) = log(src.at<uchar>(i, j) + 1);
			difference.at<float>(i, j) = log_src.at<float>(i, j) - log_gaussImg.at<float>(i, j);
			//dst.at<float>(i, j) = exp(difference.at<float>(i, j));
		}
	// 归一化到0-255范围内(疑问:此处对差分图像归一化反而图像显得正常,参考https://blog.csdn.net/TmacDu/article/details/103499795博主也是这样实现)
	// 计算带颜色恢复的归一化放到最后,此处注释
	//cv::normalize(difference, dst, 0, 255, cv::NORM_MINMAX, CV_8U);

	return difference;
}

/*
* @param cv::Mat src	输入图像
* @param cv::Mat& dst	输出图像
* @param double sigma   高斯核的标准差
* @breif 单尺度Retinex图像处理
*/
void retinex_process(const cv::Mat& src, cv::Mat& dst, double sigma)
{
	std::vector<cv::Mat> channels;
	std::vector<cv::Mat> channels_dst;
	cv::split(src, channels);
	for (int i = 0; i < channels.size(); i++)
	{
		channels_dst.push_back(single_scale_retinex(channels[i], sigma));
	}
	cv::merge(channels_dst, dst);
}

/*
* @param cv::Mat src	输入图像
* @param cv::Mat& dst	输出图像
* @param std::vector<double> sigma   高斯核的标准差
* @param std::vector<double> w   权重系数
* @breif 多尺度Retinex图像处理
*/
void multi_retinex_process(const cv::Mat& src, cv::Mat& dst, std::vector<double>& sigma, std::vector<double>& w)
{
	std::vector<cv::Mat> temp(sigma.size());
	for (int i = 0; i < sigma.size(); i++)
	{
		retinex_process(src, temp[i], sigma[i]);
	}
	for (int i = 0; i < w.size(); i++)
	{
		dst += w[i] * temp[i];
	}
}

/*
* @param cv::Mat src	输入图像
* @param cv::Mat& dst	输出图像
* @param double a   调节因子
* @param double b   增益常数
* @breif 计算颜色恢复因子
*/
void color_restoration(const cv::Mat& src, cv::Mat& dst, double a, double b)
{
	dst = cv::Mat(src.size(), CV_32FC3);
	for (int i = 0; i < src.rows; i++)
		for (int j = 0; j < src.cols; j++)
		{
			int sum = src.at<cv::Vec3b>(i, j)[0] + src.at<cv::Vec3b>(i, j)[1] + src.at<cv::Vec3b>(i, j)[2];
			dst.at<cv::Vec3f>(i, j)[0] = b * (log(a * src.at<cv::Vec3b>(i, j)[0] + 1.0) - log(sum + 1.0));
			dst.at<cv::Vec3f>(i, j)[1] = b * (log(a * src.at<cv::Vec3b>(i, j)[1] + 1.0) - log(sum + 1.0));
			dst.at<cv::Vec3f>(i, j)[2] = b * (log(a * src.at<cv::Vec3b>(i, j)[2] + 1.0) - log(sum + 1.0));
		}
}

/*
* @param cv::Mat src	输入图像
* @param cv::Mat& dst	输出图像
* @param std::vector<double> sigma   高斯核的标准差
* @param std::vector<double> w   权重系数
* @param double G   增益系数
* @param double t   偏移量系数
* @param double a   调节因子
* @param double b   增益常数
* @breif 带颜色恢复的多尺度Retinex图像处理
*/
void multi_retinex_color_restoration_process(const cv::Mat& src, cv::Mat& dst, std::vector<double>& sigma, std::vector<double>& w, double G, double t, double a, double b)
{
	dst.convertTo(dst, CV_32FC3);
	//计算多尺度Retinex图像
	cv::Mat multiRSImg(src.size(), CV_32FC3, cv::Scalar(0, 0, 0));
	multi_retinex_process(src, multiRSImg, sigma, w);

	//计算颜色恢复因子
	cv::Mat colorResImg(src.size(), CV_32FC3, cv::Scalar(0, 0, 0));
	color_restoration(src, colorResImg, a, b);

	//进行带颜色恢复的多尺度Retinex计算
	//关键点:saturate_cast<uchar>相当于对图像色彩做了保护
	for (int i = 0; i < src.rows; i++)
		for (int j = 0; j < src.cols; j++)
		{
			dst.at<cv::Vec3f>(i, j)[0] = saturate_cast<uchar>(G * ((multiRSImg.at<cv::Vec3f>(i, j)[0] * colorResImg.at<cv::Vec3f>(i, j)[0]) + t));
			dst.at<cv::Vec3f>(i, j)[1] = saturate_cast<uchar>(G * ((multiRSImg.at<cv::Vec3f>(i, j)[1] * colorResImg.at<cv::Vec3f>(i, j)[1]) + t));
			dst.at<cv::Vec3f>(i, j)[2] = saturate_cast<uchar>(G * ((multiRSImg.at<cv::Vec3f>(i, j)[2] * colorResImg.at<cv::Vec3f>(i, j)[2]) + t));
		}
	cv::normalize(dst, dst, 0, 255, cv::NORM_MINMAX, CV_8UC3);
}

int main()
{
	// 读取图片
	string filepath = "F://work_study//algorithm_demo//retinex_test4.jpg";
	cv::Mat src = cv::imread(filepath);
	if (src.empty())
	{
		return -1;
	}
	cv::Mat dst(src.size(), CV_8UC3, cv::Scalar(0, 0, 0));

	//高斯滤波器的尺度
	std::vector<double> sigma = { 15,80,250 };
	//各个尺度下的SSR的权重系数
	std::vector<double> w(3, 1 / 3.0);

	multi_retinex_color_restoration_process(src, dst, sigma, w, 5, 25, 125, 46);


	cv::imwrite("dst.jpg", dst);
	cv::waitKey(0);
	return 0;
}

3.结果展示

原图
MSRCR
参数比较多,不好调,大家可以阅读一位大佬写的文章,只需要调一个参数,文章链接:MSRCR
本文调节的参数在代码中,尝试很久,效果跟大佬文章效果类似。


总结

本文介绍了单尺度、多尺度、带颜色恢复的Retinex的算法原理和实现,使用C++和Opencv一步一步进行实现,代码结构简单清晰,便于阅读,但是效率有待提高,后续对代码进行重构,欢迎大家阅读和讨论代码中的不足。
本文代码均已在本地运行正确,有问题欢迎交流。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1619229.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32单片机C语言模块化编程实战:按键控制LED灯并串口打印详解与示例

一、开发环境 硬件&#xff1a;正点原子探索者 V3 STM32F407 开发板 单片机&#xff1a;STM32F407ZGT6 Keil版本&#xff1a;5.32 STM32CubeMX版本&#xff1a;6.9.2 STM32Cube MCU Packges版本&#xff1a;STM32F4 V1.27.1 虽然这里演示的是STM32F407&#xff0c;但是ST…

JetBrains PhpStorm v2024.1 安装教程 (PHP集成开发IDE)

前言 PhpStorm是由JetBrains推出的一款轻量级集成开发环境&#xff0c;专为PHP开发者而设计。该软件融合了智能的HTML/CSS/JavaScript/PHP编辑器、代码质量分析工具、版本控制系统集成&#xff08;包括SVN和GIT&#xff09;、调试和测试等功能。除此之外&#xff0c;PhpStorm还…

FPGA秋招-笔记整理(1)

一、关键路径 关键路径通常是指同步逻辑电路中&#xff0c;组合逻辑时延最大的路径&#xff08;这里我认为还需要加上布线的延迟&#xff09;&#xff0c;也就是说关键路径是对设计性能起决定性影响的时序路径。也就是静态时序报告中WNS&#xff08;Worst Nagative Slack&…

【计算机毕业设计】jspm医院门诊挂号系统——后附源码

&#x1f389;**欢迎来到琛哥的技术世界&#xff01;**&#x1f389; &#x1f4d8; 博主小档案&#xff1a; 琛哥&#xff0c;一名来自世界500强的资深程序猿&#xff0c;毕业于国内知名985高校。 &#x1f527; 技术专长&#xff1a; 琛哥在深度学习任务中展现出卓越的能力&a…

【服务器部署篇】Linux下Ansible安装和配置

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0c;产…

编译器的学习

常用的编译器&#xff1a; GCCVisual CClang&#xff08;LLVM&#xff09;&#xff1a; Clang 可以被看作是建立在 LLVM 之上的一个项目, 实际上LLVM是clang的后端&#xff0c;clang作为前端前端生成LLVM IR&#xff0c;https://zhuanlan.zhihu.com/p/656699711MSVC &#xff…

构建安全高效的前端权限控制系统

✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心哦&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; ✨✨ 帅哥美女们&#xff0c;我们共同加油&#xff01;一起进步&am…

计算机网络相关知识总结

一、概述 计算机网络可以极大扩展计算机系统的功能机器应用范围&#xff0c;提高可靠性&#xff0c;在为用户提供放方便的同时&#xff0c;减少了整体系统费用&#xff0c;提高性价比。 计算机网络的功能主要有&#xff1a;1. 数据共享&#xff1b;2. 资源共享&#xff1b;3. 管…

《系统架构设计师教程(第2版)》第15章-面向服务架构设计理论与实践-05-SOA设计模式

文章目录 1. 服务注册表模式1.1 服务注册表1.2 SOA治理功能1.3 注册表中的配置文件 2. 企业服务总线&#xff08;ESB&#xff09;模式3. Synchro ESB3. 微服务模式3.1 概述3.2 微服务架构模式方案3.2.1 聚合器微服务1&#xff09;概述2&#xff09;几种特殊的聚合微服务 3.2.2 …

ElasticSearch笔记一

随着这个业务的发展&#xff0c;我们的数据量越来越庞大。那么传统的这种mysql的数据库就渐渐的难以满足我们复杂的业务需求了。 所以在微服务架构下一般都会用到一种分布式搜索的技术。那么今天呢我们就会带着大家去学习分布搜索当中最流行的一种ElasticSearch&#xff0c;Ela…

Android Studio开发之路(八)Spinner样式设置

一、需求 白色背景显示下拉框按钮 问题&#xff1a; 设置Spinner的背景可以通过设置background&#xff1a; android:background"color/white",但是一旦设置了这个值&#xff0c;右侧的下拉按钮就会消失 方法一、自定义一个style&#xff08;不成功&#xff09; …

1张图片+3090显卡微调Qwen-VL视觉语言大模型(仅做演示、效果还需加大数据量)

原项目地址&#xff1a;https://github.com/QwenLM/Qwen-VL/blob/master/README_CN.md 环境本地部署&#xff08;见之前博文&#xff09; 【本地部署 】23.08 阿里Qwen-VL&#xff1a;能对图片理解、定位物体、读取文字的视觉语言模型 (推理最低12G显存) 一、数据集格式说明 …

网络安全之SQL注入漏洞复现(中篇)(技术进阶)

目录 一&#xff0c;报错注入 二&#xff0c;布尔盲注 三&#xff0c;sleep延时盲注 四&#xff0c;DNSlogs 盲注 五&#xff0c;二次注入 六&#xff0c;堆叠注入 总结 一&#xff0c;报错注入 报错注入就是在错误信息中执行 sql 语句&#xff0c;利用网站的报错信息来带…

HTML:PC和手机的自适应图形布局样例

作者:私语茶馆 1.前言 有时我们需要开发一个自适应PC和手机的HTML页面,由于屏幕大小不同,会涉及到自动部署。W3School提供了一个非常好的案例:Responsive Image Gallery。本文利用独立CSS文件详细介绍一下这个案例。 2.案例详细介绍 2.1.Project项目文件结构 企业级项目…

代码随想录算法训练营第四十六天| LeetCode139.单词拆分

一、LeetCode139.单词拆分 题目链接/文章讲解/视频讲解&#xff1a;https://programmercarl.com/0139.%E5%8D%95%E8%AF%8D%E6%8B%86%E5%88%86.html 状态&#xff1a;已解决 1.思路 单词明显就是物品&#xff0c;字符串s明显就是背包&#xff0c;那么问题就变成了物品能不能把背…

小程序 rich-text 解析富文本 图片过大时如何自适应?

在微信小程序中&#xff0c;用rich-text 解析后端返回的数据&#xff0c;当图片尺寸太大时&#xff0c;会溢出屏幕&#xff0c;导致横向出现滚动 查看富文本代码 图片是用 <img 标签&#xff0c;所以写个正则匹配一下图片标签&#xff0c;手动加上样式即可 // content 为后…

文献速递:深度学习胶质瘤诊断---空间细胞结构预测胶质母细胞瘤的预后

Title 题目 Spatial cellular architecture predicts prognosis in glioblastoma 空间细胞结构预测胶质母细胞瘤的预后 01文献速递介绍 胶质母细胞瘤的治疗耐药性的关键驱动因素是肿瘤内的异质性和细胞状态的可塑性。在这里&#xff0c;我们调查了空间细胞组织与胶质母细胞瘤…

图像哈希:全局+局部提取特征

文章信息 作者&#xff1a;梁小平&#xff0c;唐振军期刊&#xff1a;ACM Trans. Multimedia Comput. Commun. Appl&#xff08;三区&#xff09;题目&#xff1a;Robust Hashing via Global and Local Invariant Features for Image Copy Detection 目的、实验步骤及结论 目…

分布式与一致性协议之拜占庭将军问题(三)

拜占庭将军问题 叛将先发送消息 如果是叛将楚先发送作战消息&#xff0c;干扰作战计划&#xff0c;结果会有所不同吗&#xff1f; 在第一轮作战信息协商中&#xff0c;楚向苏秦发送作战指令"进攻",向齐、燕发送作战指令"撤退"&#xff0c;如图所示(当然还…

排序算法:顺序查找

简介 顺序查找&#xff08;也称为线性查找&#xff09;是一种简单直观的搜索算法。按照顺序逐个比较列表或数组中的元素&#xff0c;直到找到目标元素或搜索完整个列表。 应用场景 数据集比较小&#xff0c;无需使用复杂的算法。数据集没有排序&#xff0c;不能使用二分查找…