如何利用OpenCV4.9离散傅里叶变换

news2024/11/17 8:29:35

返回:OpenCV系列文章目录(持续更新中......)

上一篇:如何利用OpenCV4.9 更改图像的对比度和亮度

下一篇:

目标

我们将寻求以下问题的答案:

  • 什么是傅里叶变换,为什么要使用它?
  • 如何在 OpenCV 中做到这一点?
  • 使用以下函数: copyMakeBorder() , merge() , dft() , getOptimalDFTSize() , log()normalize() .

源代码

你可以在官方网站下载相关源代码。

以下 dft()  的用法示例:

C++

#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp" 
#include <iostream> 
using namespace cv;
using namespace std; 
static void help(char ** argv)
{
 cout << endl
 << "This program demonstrated the use of the discrete Fourier transform (DFT). " << endl
 << "The dft of an image is taken and it's power spectrum is displayed." << endl << endl
 << "Usage:" << endl
 << argv[0] << " [image_name -- default lena.jpg]" << endl << endl;
} 
int main(int argc, char ** argv)
{
 help(argv); 
 const char* filename = argc >=2 ? argv[1] : "lena.jpg"; 
 Mat I = imread( samples::findFile( filename ), IMREAD_GRAYSCALE);
 if( I.empty()){
 cout << "Error opening image" << endl;
 return EXIT_FAILURE;
 } 
 Mat padded; //expand input image to optimal size
 int m = getOptimalDFTSize( I.rows );
 int n = getOptimalDFTSize( I.cols ); // on the border add zero values
 copyMakeBorder(I, padded, 0, m - I.rows, 0, n - I.cols, BORDER_CONSTANT, Scalar::all(0)); 
 Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
 Mat complexI;
 merge(planes, 2, complexI); // Add to the expanded another plane with zeros 
 dft(complexI, complexI); // this way the result may fit in the source matrix 
 // compute the magnitude and switch to logarithmic scale
 // => log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
 split(complexI, planes); // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
 magnitude(planes[0], planes[1], planes[0]);// planes[0] = magnitude
 Mat magI = planes[0]; 
 magI += Scalar::all(1); // switch to logarithmic scale
 log(magI, magI); 
 // crop the spectrum, if it has an odd number of rows or columns
 magI = magI(Rect(0, 0, magI.cols & -2, magI.rows & -2)); 
 // rearrange the quadrants of Fourier image so that the origin is at the image center
 int cx = magI.cols/2;
 int cy = magI.rows/2; 
 Mat q0(magI, Rect(0, 0, cx, cy)); // Top-Left - Create a ROI per quadrant
 Mat q1(magI, Rect(cx, 0, cx, cy)); // Top-Right
 Mat q2(magI, Rect(0, cy, cx, cy)); // Bottom-Left
 Mat q3(magI, Rect(cx, cy, cx, cy)); // Bottom-Right 
 Mat tmp; // swap quadrants (Top-Left with Bottom-Right)
 q0.copyTo(tmp);
 q3.copyTo(q0);
 tmp.copyTo(q3); 
 q1.copyTo(tmp); // swap quadrant (Top-Right with Bottom-Left)
 q2.copyTo(q1);
 tmp.copyTo(q2); 
 normalize(magI, magI, 0, 1, NORM_MINMAX); // Transform the matrix with float values into a
 // viewable image form (float between values 0 and 1). 
 imshow("Input Image" , I ); // Show the result
 imshow("spectrum magnitude", magI);
 waitKey(); 
 return EXIT_SUCCESS;
}

Java

import org.opencv.core.*;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs; 
import java.util.List;
import java.util.*; 
class DiscreteFourierTransformRun{
 private void help() {
 System.out.println("" +
 "This program demonstrated the use of the discrete Fourier transform (DFT). \n" +
 "The dft of an image is taken and it's power spectrum is displayed.\n" +
 "Usage:\n" +
 "./DiscreteFourierTransform [image_name -- default ../data/lena.jpg]");
 } 
 public void run(String[] args){ 
 help(); 
 String filename = ((args.length > 0) ? args[0] : "../data/lena.jpg"); 
 Mat I = Imgcodecs.imread(filename, Imgcodecs.IMREAD_GRAYSCALE);
 if( I.empty() ) {
 System.out.println("Error opening image");
 System.exit(-1);
 } 
 Mat padded = new Mat(); //expand input image to optimal size
 int m = Core.getOptimalDFTSize( I.rows() );
 int n = Core.getOptimalDFTSize( I.cols() ); // on the border add zero values
 Core.copyMakeBorder(I, padded, 0, m - I.rows(), 0, n - I.cols(), Core.BORDER_CONSTANT, Scalar.all(0)); 
 List<Mat> planes = new ArrayList<Mat>();
 padded.convertTo(padded, CvType.CV_32F);
 planes.add(padded);
 planes.add(Mat.zeros(padded.size(), CvType.CV_32F));
 Mat complexI = new Mat();
 Core.merge(planes, complexI); // Add to the expanded another plane with zeros 
 Core.dft(complexI, complexI); // this way the result may fit in the source matrix 
 // compute the magnitude and switch to logarithmic scale
 // => log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
 Core.split(complexI, planes); // planes.get(0) = Re(DFT(I)
 // planes.get(1) = Im(DFT(I))
 Core.magnitude(planes.get(0), planes.get(1), planes.get(0));// planes.get(0) = magnitude
 Mat magI = planes.get(0); 
 Mat matOfOnes = Mat.ones(magI.size(), magI.type());
 Core.add(matOfOnes, magI, magI); // switch to logarithmic scale
 Core.log(magI, magI); 
 // crop the spectrum, if it has an odd number of rows or columns
 magI = magI.submat(new Rect(0, 0, magI.cols() & -2, magI.rows() & -2)); 
 // rearrange the quadrants of Fourier image so that the origin is at the image center
 int cx = magI.cols()/2;
 int cy = magI.rows()/2; 
 Mat q0 = new Mat(magI, new Rect(0, 0, cx, cy)); // Top-Left - Create a ROI per quadrant
 Mat q1 = new Mat(magI, new Rect(cx, 0, cx, cy)); // Top-Right
 Mat q2 = new Mat(magI, new Rect(0, cy, cx, cy)); // Bottom-Left
 Mat q3 = new Mat(magI, new Rect(cx, cy, cx, cy)); // Bottom-Right 
 Mat tmp = new Mat(); // swap quadrants (Top-Left with Bottom-Right)
 q0.copyTo(tmp);
 q3.copyTo(q0);
 tmp.copyTo(q3); 
 q1.copyTo(tmp); // swap quadrant (Top-Right with Bottom-Left)
 q2.copyTo(q1);
 tmp.copyTo(q2); 
 magI.convertTo(magI, CvType.CV_8UC1);
 Core.normalize(magI, magI, 0, 255, Core.NORM_MINMAX, CvType.CV_8UC1); // Transform the matrix with float values
 // into a viewable image form (float between
 // values 0 and 255). 
 HighGui.imshow("Input Image" , I ); // Show the result
 HighGui.imshow("Spectrum Magnitude", magI);
 HighGui.waitKey(); 
 System.exit(0);
 }
} 
public class DiscreteFourierTransform {
 public static void main(String[] args) {
 // Load the native library.
 System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
 new DiscreteFourierTransformRun().run(args);
 }
}

Python 

from __future__ import print_function
import sys 
import cv2 as cv
import numpy as np 
def print_help():
 print('''
 This program demonstrated the use of the discrete Fourier transform (DFT).
 The dft of an image is taken and it's power spectrum is displayed.
 Usage:
 discrete_fourier_transform.py [image_name -- default lena.jpg]''') 
def main(argv): 
 print_help() 
 filename = argv[0] if len(argv) > 0 else 'lena.jpg' 
 I = cv.imread(cv.samples.findFile(filename), cv.IMREAD_GRAYSCALE)
 if I is None:
 print('Error opening image')
 return -1 
 rows, cols = I.shape
 m = cv.getOptimalDFTSize( rows )
 n = cv.getOptimalDFTSize( cols )
 padded = cv.copyMakeBorder(I, 0, m - rows, 0, n - cols, cv.BORDER_CONSTANT, value=[0, 0, 0]) 
 planes = [np.float32(padded), np.zeros(padded.shape, np.float32)]
 complexI = cv.merge(planes) # Add to the expanded another plane with zeros 
 cv.dft(complexI, complexI) # this way the result may fit in the source matrix 
 cv.split(complexI, planes) # planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
 cv.magnitude(planes[0], planes[1], planes[0])# planes[0] = magnitude
 magI = planes[0] 
 matOfOnes = np.ones(magI.shape, dtype=magI.dtype)
 cv.add(matOfOnes, magI, magI) # switch to logarithmic scale
 cv.log(magI, magI) 
 magI_rows, magI_cols = magI.shape
 # crop the spectrum, if it has an odd number of rows or columns
 magI = magI[0:(magI_rows & -2), 0:(magI_cols & -2)]
 cx = int(magI_rows/2)
 cy = int(magI_cols/2) 
 q0 = magI[0:cx, 0:cy] # Top-Left - Create a ROI per quadrant
 q1 = magI[cx:cx+cx, 0:cy] # Top-Right
 q2 = magI[0:cx, cy:cy+cy] # Bottom-Left
 q3 = magI[cx:cx+cx, cy:cy+cy] # Bottom-Right 
 tmp = np.copy(q0) # swap quadrants (Top-Left with Bottom-Right)
 magI[0:cx, 0:cy] = q3
 magI[cx:cx + cx, cy:cy + cy] = tmp 
 tmp = np.copy(q1) # swap quadrant (Top-Right with Bottom-Left)
 magI[cx:cx + cx, 0:cy] = q2
 magI[0:cx, cy:cy + cy] = tmp 
 cv.normalize(magI, magI, 0, 1, cv.NORM_MINMAX) # Transform the matrix with float values into a 
 cv.imshow("Input Image" , I ) # Show the result
 cv.imshow("spectrum magnitude", magI)
 cv.waitKey() 
if __name__ == "__main__":
 main(sys.argv[1:])

解释:

傅里叶变换会将图像分解为正弦和余弦分量。换句话说,它将图像从其空间域转换为其频域。这个想法是,任何函数都可以精确地近似于无限正弦和余弦函数的总和。傅里叶变换是一种如何做到这一点的方法。从数学上讲,二维图像傅里叶变换是:

这里 f 是其空间域中的图像值,F 是其频域中的图像值。变换的结果是复数。可以通过真实图像和数图像或通过幅度相位图像来显示这一点。然而,在整个图像处理算法中,只有幅度图像是有趣的,因为它包含了我们需要的有关图像几何结构的所有信息。但是,如果您打算以这些形式对图像进行一些修改,然后需要重新转换它,则需要保留这两种形式。

在此示例中,我将演示如何计算和显示傅里叶变换的幅度图像。在数字图像的情况下是离散的。这意味着它们可能会从给定的域值中获取一个值。例如,在基本灰度中,图像值通常介于 0 到 255 之间。因此,傅里叶变换也需要是离散类型的,从而产生离散傅里叶变换 (DFT)。每当您需要从几何角度确定图像的结构时,您都需要使用它。以下是要遵循的步骤(如果是灰度输入图像 I):

将图像扩展到最佳大小

DFT 的性能取决于图像大小。对于数字 2、3 和 5 的倍数的图像大小,它往往是最快的。因此,为了实现最佳性能,通常最好将边框值填充到图像上,以获得具有此类特征的大小。getOptimalDFTSize()返回这个最佳大小,我们可以使用 copyMakeBorder() 函数来扩展图像的边框(附加的像素以零初始化):

c++:

 Mat padded; //expand input image to optimal size
 int m = getOptimalDFTSize( I.rows );
 int n = getOptimalDFTSize( I.cols ); // on the border add zero values
 copyMakeBorder(I, padded, 0, m - I.rows, 0, n - I.cols, BORDER_CONSTANT, Scalar::all(0));

Java:

 Mat padded = new Mat(); //expand input image to optimal size
 int m = Core.getOptimalDFTSize( I.rows() );
 int n = Core.getOptimalDFTSize( I.cols() ); // on the border add zero values
 Core.copyMakeBorder(I, padded, 0, m - I.rows(), 0, n - I.cols(), Core.BORDER_CONSTANT, Scalar.all(0));

python: 

 rows, cols = I.shape
 m = cv.getOptimalDFTSize( rows )
 n = cv.getOptimalDFTSize( cols )
 padded = cv.copyMakeBorder(I, 0, m - rows, 0, n - cols, cv.BORDER_CONSTANT, value=[0, 0, 0])

为复杂价值和真实价值腾出空间

傅里叶变换的结果很复杂。这意味着对于每个图像值,结果是两个图像值(每个组件一个)。此外,频域范围比空间对应物大得多。因此,我们通常至少以浮点格式存储这些内容。因此,我们将输入图像转换为此类型,并使用另一个通道对其进行扩展以保存复数值:

c++:

 Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
 Mat complexI;
 merge(planes, 2, complexI); // Add to the expanded another plane with zeros

 Java:

 Mat padded = new Mat(); //expand input image to optimal size
 int m = Core.getOptimalDFTSize( I.rows() );
 int n = Core.getOptimalDFTSize( I.cols() ); // on the border add zero values
 Core.copyMakeBorder(I, padded, 0, m - I.rows(), 0, n - I.cols(), Core.BORDER_CONSTANT, Scalar.all(0));

Python:

 rows, cols = I.shape
 m = cv.getOptimalDFTSize( rows )
 n = cv.getOptimalDFTSize( cols )
 padded = cv.copyMakeBorder(I, 0, m - rows, 0, n - cols, cv.BORDER_CONSTANT, value=[0, 0, 0])

进行离散傅里叶变换

可以就地计算(输入与输出相同):

C++:

dft(complexI, complexI); // this way the result may fit in the source matrix

 Java:

 Core.dft(complexI, complexI); // this way the result may fit in the source matrix

Python: 

 cv.dft(complexI, complexI) # this way the result may fit in the source matrix

将实数值和复数值转换为量级

复数有一个实数(Re)和一个复数(虚数-Im)部分。DFT 的结果是复数。DFT 的量级为:

翻译成 OpenCV 代码:

C++:

 split(complexI, planes); // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
 magnitude(planes[0], planes[1], planes[0]);// planes[0] = magnitude
 Mat magI = planes[0];

Java:

 Core.split(complexI, planes); // planes.get(0) = Re(DFT(I)
 // planes.get(1) = Im(DFT(I))
 Core.magnitude(planes.get(0), planes.get(1), planes.get(0));// planes.get(0) = magnitude
 Mat magI = planes.get(0);

Python:

 cv.split(complexI, planes) # planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
 cv.magnitude(planes[0], planes[1], planes[0])# planes[0] = magnitude
 magI = planes[0]

切换到对数刻度

事实证明,傅里叶系数的动态范围太大,无法显示在屏幕上。我们有一些小的和一些高的变化值,我们无法像这样观察到。因此,高值将全部变成白点,而小值则变成黑点。为了使用灰度值进行可视化,我们可以将线性刻度转换为对数刻度:

翻译成 OpenCV 代码:

C++:

 magI += Scalar::all(1); // switch to logarithmic scale
 log(magI, magI);

Java:

 Mat matOfOnes = Mat.ones(magI.size(), magI.type());
 Core.add(matOfOnes, magI, magI); // switch to logarithmic scale
 Core.log(magI, magI);

Python : 

 matOfOnes = np.ones(magI.shape, dtype=magI.dtype)
 cv.add(matOfOnes, magI, magI) # switch to logarithmic scale
 cv.log(magI, magI)

裁剪和重新排列

还记得,在第一步,我们扩展了图像吗?好吧,是时候扔掉新引入的价值观了。出于可视化目的,我们还可以重新排列结果的象限,使原点(零,零)与图像中心相对应。

C++:

 // crop the spectrum, if it has an odd number of rows or columns
 magI = magI(Rect(0, 0, magI.cols & -2, magI.rows & -2)); 
 // rearrange the quadrants of Fourier image so that the origin is at the image center
 int cx = magI.cols/2;
 int cy = magI.rows/2; 
 Mat q0(magI, Rect(0, 0, cx, cy)); // Top-Left - Create a ROI per quadrant
 Mat q1(magI, Rect(cx, 0, cx, cy)); // Top-Right
 Mat q2(magI, Rect(0, cy, cx, cy)); // Bottom-Left
 Mat q3(magI, Rect(cx, cy, cx, cy)); // Bottom-Right 
 Mat tmp; // swap quadrants (Top-Left with Bottom-Right)
 q0.copyTo(tmp);
 q3.copyTo(q0);
 tmp.copyTo(q3); 
 q1.copyTo(tmp); // swap quadrant (Top-Right with Bottom-Left)
 q2.copyTo(q1);
 tmp.copyTo(q2);

 Java:

 // crop the spectrum, if it has an odd number of rows or columns
 magI = magI.submat(new Rect(0, 0, magI.cols() & -2, magI.rows() & -2));
  // rearrange the quadrants of Fourier image so that the origin is at the image center
 int cx = magI.cols()/2;
 int cy = magI.rows()/2; 
 Mat q0 = new Mat(magI, new Rect(0, 0, cx, cy)); // Top-Left - Create a ROI per quadrant
 Mat q1 = new Mat(magI, new Rect(cx, 0, cx, cy)); // Top-Right
 Mat q2 = new Mat(magI, new Rect(0, cy, cx, cy)); // Bottom-Left
 Mat q3 = new Mat(magI, new Rect(cx, cy, cx, cy)); // Bottom-Right 
 Mat tmp = new Mat(); // swap quadrants (Top-Left with Bottom-Right)
 q0.copyTo(tmp);
 q3.copyTo(q0);
 tmp.copyTo(q3); 
 q1.copyTo(tmp); // swap quadrant (Top-Right with Bottom-Left)
 q2.copyTo(q1);
 tmp.copyTo(q2);

Python: 

 magI_rows, magI_cols = magI.shape
 # crop the spectrum, if it has an odd number of rows or columns
 magI = magI[0:(magI_rows & -2), 0:(magI_cols & -2)]
 cx = int(magI_rows/2)
 cy = int(magI_cols/2) 
 q0 = magI[0:cx, 0:cy] # Top-Left - Create a ROI per quadrant
 q1 = magI[cx:cx+cx, 0:cy] # Top-Right
 q2 = magI[0:cx, cy:cy+cy] # Bottom-Left
 q3 = magI[cx:cx+cx, cy:cy+cy] # Bottom-Right 
 tmp = np.copy(q0) # swap quadrants (Top-Left with Bottom-Right)
 magI[0:cx, 0:cy] = q3
 magI[cx:cx + cx, cy:cy + cy] = tmp 
 tmp = np.copy(q1) # swap quadrant (Top-Right with Bottom-Left)
 magI[cx:cx + cx, 0:cy] = q2
 magI[0:cx, cy:cy + cy] = tmp

正常化

出于可视化目的,再次执行此操作。我们现在有了星等,但这仍然超出了我们的图像显示范围 0 到 1。我们使用 cv::normalize() 函数将我们的值规范化到这个范围。

C++:

 normalize(magI, magI, 0, 1, NORM_MINMAX); // Transform the matrix with float values into a
 // viewable image form (float between values 0 and 1).

Java:

 Core.normalize(magI, magI, 0, 255, Core.NORM_MINMAX, CvType.CV_8UC1); // Transform the matrix with float values
 // into a viewable image form (float between
 // values 0 and 255).

python:

 cv.normalize(magI, magI, 0, 1, cv.NORM_MINMAX) # Transform the matrix with float values into a

结果

一个应用思路是确定图像中存在的几何方向。例如,让我们找出文本是否是水平的?看一些文本,你会注意到文本线条也形成了水平线,字母形成了垂直线条。在傅里叶变换的情况下,也可以看到文本片段的这两个主要组成部分。让我们使用这个水平和这个旋转的图像来描述一个文本。

如果是横向文本:

如果文本旋转:

您可以看到,频域中最有影响力的分量(幅度图像上最亮的点)遵循图像上物体的几何旋转。由此我们可以计算偏移量并执行图像旋转以校正最终的未对齐。

参考文献:

1、《Discrete Fourier Transform》-----Bernát Gábor

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

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

相关文章

Spring6 (1)

Spring 1、简介&#xff1a;2、第一个程序2、set注入2.1 简单数据类型2.2测试2.3 注入Properties2.4 p命名空间注入2.5 c命名空间注入2.6 util注入2.6 引入外部配置文件 1、简介&#xff1a; 自己的理解&#xff1a;spring其实就是一个容器&#xff0c;也可以说是一个框架&…

腾讯云轻量4核8G12M服务器配置4C8G12M详解

4核8G是云服务器的参数&#xff0c;代表云服务器的硬件配置和网络带宽&#xff0c;4核代表CPU、8G是指内存、12M代表带宽值为12Mbps&#xff0c;腾讯云百科txybk.com以腾讯云轻量应用服务器4核8G12M带宽配置为例&#xff0c;来详细介绍下服务器参数&#xff1a; 4c8g是什么意思…

高阶数据结构 <红黑树>

本文已收录至《数据结构(C/C语言)》专栏&#xff01; 作者&#xff1a;ARMCSKGT 目录 前言正文红黑树简介红黑树整体结构红黑树节点的定义红黑树主体类设计红黑树的插入函数情况一&#xff1a;变色情况二&#xff1a;变色旋转单旋情况双旋情况 完整插入代码 关于红黑树红黑树检…

鸿蒙OS实例:同步获取应用配置的【versionCode和versionName】

1.同步方式获取 首先需要导包&#xff1a; import bundleManager from ohos.bundle.bundleManager 工具类&#xff1a; public static async getVersionName(): Promise<string> {try {let bundleInfo await bundleManager.getBundleInfoForSelf(bundleManager.Bundle…

树状数组及应用

目录 1.树状数组的概念与基本编码 1.1.引导 1.2.lowbit(x) 1.3.树状数组的编码 2.树状数组的基本应用 2.1.单点修改&#xff0b;区间查询 2.2.区间修改单点查询 例题&#xff1a; 2.3.区间修改&#xff0b;区间查询 例题&#xff1a; 如果数列A是静态不变的&#xff…

并发学习25--多线程 ThreadPoolExecutor

类图&#xff1a;定义了一些重要的接口和实现类 线程池的几种状态&#xff1a; ThreadPoolExecutor构造方法 1.救急线程 线程池中会有核心线程和救急线程&#xff1b;救急线程数最大线程数-核心线程数。而救急线程会在阻塞队列已经占满的情况下&#xff0c;执行下一个即将要被…

RK3568-开启ptp服务

硬件支持 mac或者phy需要支持ptp驱动支持 CONFIG_PTP_1588_CLOCK=y虚拟机端:虚拟机只支持软件时间戳。 安装ptp服务:sudo apt-get install linuxptp 修改ptp服务:sudo vi /lib/systemd/system/ptp4l.service,修改为ens33网口,-S表示使用软件时间戳。forlinx@ubuntu:~$ s…

Redis修改开源协议,6大备胎重见天日

背景&#xff1a;Redis2018年以来修改了多次开源协议&#xff0c;以前是把一些高级功能收费&#xff0c;这次彻底怒了&#xff0c;把核心代码的协议修改为RSALv2和SSPL双重协议&#xff0c;这个修改对普通用户不受影响&#xff0c;是向所有云厂商开炮&#xff0c;以后云厂商将不…

迁移android studio 模拟器位置

android studio 初始位置是安装在c盘&#xff0c;若是要迁移需 1创建一个目标位置如我的F:/avd 2在系统环境变量里面设置新的地址 变量名&#xff1a;ANDROID_SDK_HOME 变量值&#xff1a;F:/avd 3最重要的是文件复制&#xff0c;将C盘里面avd的上层目录.android的目录整体…

C++ static静态变量详解

目录 觉得有用就给博主点个赞吧&#xff01;谢谢啦&#xff01;嘻嘻嘻 概念&#xff1a; 特性 如何计算一个类创建了多少个对象&#xff1f; 概念&#xff1a; 用static关键字修饰的成员变量叫做静态成员变量 在类内部&#xff0c;但是属于全局&#xff0c;不属于任意一个…

前端调用接口地址跨越问题,nginx配置处理

在nginx配置里面添加add_header如下&#xff1a; add_header Access-Control-Allow-Origin *; #add_header Access-Control-Allow-Origin http://localhost:8080 always; add_header Access-Control-Allow-Methods GET, POST, PUT, D…

JavaScript Uncaught ReferenceError: WScript is not defined

项目场景&#xff1a; 最近在Visual Studio 2019上编译libmodbus库&#xff0c;出现了很多问题&#xff0c;一一解决特此记录下来。 问题描述 首先就是configure.js文件的问题&#xff0c;它会生成两个很重要的头文件modbus_version.h和config.h&#xff0c;这两个头文件其中…

【Lazy ORM 框架学习】

Gitee 点赞关注不迷路 项目地址 快速入门 模块所属层级描述快照版本正式版本wu-database-lazy-lambdalambda针对不同数据源wu-database-lazy-orm-coreorm 核心orm核心处理wu-database-lazy-sqlsql核心处理成处理sql解析、sql执行、sql映射wu-elasticsearch-starterESESwu-hb…

【React】vite + react 项目,进行配置 eslint

安装与配置 eslint 1 安装 eslint @babel/eslint-parser2 初始化配置 eslint3 安装 vite-plugin-eslint4 配置 vite.config.js 文件5 修改 eslint 默认配置1 安装 eslint @babel/eslint-parser npm i -D eslint @babel/eslint-parser2 初始化配置 eslint npx eslint --init相…

Vmware虚拟机无法用root直连说明

Vmware虚拟机无法用root直连说明 背景目的SSH服务介绍无法连接检查配置 背景 今天在VM上新装了一套Centos-stream-9系统&#xff0c;网络适配器的连接方式采用的是桥接&#xff0c;安装好虚拟机后&#xff0c;在本地用ssh工具进行远程连接&#xff0c;ip、用户、密码均是成功的…

【正点原子FreeRTOS学习笔记】————(12)信号量

这里写目录标题 一、信号量的简介&#xff08;了解&#xff09;二、二值信号量&#xff08;熟悉&#xff09;三、二值信号量实验&#xff08;掌握&#xff09;四、计数型信号量&#xff08;熟悉&#xff09;五、计数型信号量实验&#xff08;掌握&#xff09;六、优先级翻转简介…

LInux|命令行参数|环境变量

LInux|命令行参数|环境变量 命令行参数main的参数之argc&#xff0c;argv几个小知识<font color#0099ff size 5 face"黑体">1.子进程默认能看到并访问父进程的数据<font color#4b0082 size 5 face"黑体">2.命令行创建的程序父进程都是bash 环…

iterm2下使用tmux如果左右分屏用鼠标选中文字跨越pane的问题

原来的样子 如图所示&#xff0c;我开了左右分屏的tmux&#xff0c;如果我指向选择右边的三行div&#xff0c;用鼠标选中之后&#xff0c;会发现把左边的内容也框选了。 解决办法 Edit -》 Selection Respects Soft Boundaries 勾选这个功能&#xff08;选择遵循软边界&#…

秒杀VLOOKUP函数,查找数字我只服SUMIF函数

一提到数据查询&#xff0c;相信很多人的第一反应就是使用Vlookup函数。但是今天我想跟大家分享另一种比较另类的数据查询方式&#xff0c;就是利用SUMIF函数&#xff0c;相较于Vlookup函数它更加的简单灵活、且不容易出错&#xff0c;下面我们就来学习下它的使用方法。 1、常…

win10开启了hyper-v,docker 启动还是报错 docker desktop windows hypervisor is not present

问题 在安装了docker windows版本后启动 docker报错docker desktop windows hypervisor is not present 解决措施 首先确认windows功能是否打开Hyper-v 勾选后重启&#xff0c;再次启动 启动后仍报这个错误&#xff0c;是Hyper-v没有设置成功 使用cmd禁用再启用 一.禁用h…