OpenCV图片校正

news/2024/5/20 23:22:34/文章来源:https://blog.csdn.net/liuqingsongmsdn2014/article/details/132393175

OpenCV图片校正

  • 背景
  • 几种校正方法
  • 1.傅里叶变换 + 霍夫变换+ 直线 + 角度 + 旋转
  • 3.四点透视 + 角度 + 旋转
  • 4.检测矩形轮廓 + 角度 + 旋转
  • 参考

背景

遇到偏的图片想要校正成水平或者垂直的。

几种校正方法

对于倾斜的图片通过矫正可以得到水平的图片。一般有如下几种基于opencv的组合方式进行图片矫正。

  • 1、傅里叶变换 + 霍夫变换+ 直线 + 角度 + 旋转
  • 2、边缘检测 + 霍夫变换 + 直线+角度 + 旋转
  • 3、四点透视 + 角度 + 旋转
  • 4、检测矩形轮廓 + 角度 + 旋转

1.傅里叶变换 + 霍夫变换+ 直线 + 角度 + 旋转

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>using namespace cv;
using namespace std;// 二值化阈值
#define GRAY_THRESH 150// 直线上点的个数
#define HOUGH_VOTE 50int main(int argc, char **argv)
{//Read a single-channel imageconst char* filename = "31.png";Mat srcImg = imread(filename, CV_LOAD_IMAGE_GRAYSCALE);if (srcImg.empty())return -1;imshow("source", srcImg);Point center(srcImg.cols / 2, srcImg.rows / 2);//Expand image to an optimal size, for faster processing speed//Set widths of borders in four directions//If borderType==BORDER_CONSTANT, fill the borders with (0,0,0)Mat padded;int opWidth = getOptimalDFTSize(srcImg.rows);int opHeight = getOptimalDFTSize(srcImg.cols);copyMakeBorder(srcImg, padded, 0, opWidth - srcImg.rows, 0, opHeight - srcImg.cols, BORDER_CONSTANT, Scalar::all(0));Mat planes[] = { Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F) };Mat comImg;//Merge into a double-channel imagemerge(planes, 2, comImg);//Use the same image as input and output,//so that the results can fit in Mat welldft(comImg, comImg);//Compute the magnitude//planes[0]=Re(DFT(I)), planes[1]=Im(DFT(I))//magnitude=sqrt(Re^2+Im^2)split(comImg, planes);magnitude(planes[0], planes[1], planes[0]);//Switch to logarithmic scale, for better visual results//M2=log(1+M1)Mat magMat = planes[0];magMat += Scalar::all(1);log(magMat, magMat);//Crop the spectrum//Width and height of magMat should be even, so that they can be divided by 2//-2 is 11111110 in binary system, operator & make sure width and height are always evenmagMat = magMat(Rect(0, 0, magMat.cols & -2, magMat.rows & -2));//Rearrange the quadrants of Fourier image,//so that the origin is at the center of image,//and move the high frequency to the cornersint cx = magMat.cols / 2;int cy = magMat.rows / 2;Mat q0(magMat, Rect(0, 0, cx, cy));Mat q1(magMat, Rect(0, cy, cx, cy));Mat q2(magMat, Rect(cx, cy, cx, cy));Mat q3(magMat, Rect(cx, 0, cx, cy));Mat tmp;q0.copyTo(tmp);q2.copyTo(q0);tmp.copyTo(q2);q1.copyTo(tmp);q3.copyTo(q1);tmp.copyTo(q3);//Normalize the magnitude to [0,1], then to[0,255]normalize(magMat, magMat, 0, 1, CV_MINMAX);Mat magImg(magMat.size(), CV_8UC1);magMat.convertTo(magImg, CV_8UC1, 255, 0);imshow("magnitude", magImg);//imwrite("imageText_mag.jpg",magImg);//Turn into binary imagethreshold(magImg, magImg, GRAY_THRESH, 255, CV_THRESH_BINARY);imshow("mag_binary", magImg);//imwrite("imageText_bin.jpg",magImg);//Find lines with Hough Transformationvector<Vec2f> lines;float pi180 = (float)CV_PI / 180;Mat linImg(magImg.size(), CV_8UC3);HoughLines(magImg, lines, 1, pi180, HOUGH_VOTE, 0, 0);int numLines = lines.size();for (int l = 0; l<numLines; l++){float rho = lines[l][0], theta = lines[l][1];Point pt1, pt2;double a = cos(theta), b = sin(theta);double x0 = a*rho, y0 = b*rho;pt1.x = cvRound(x0 + 1000 * (-b));pt1.y = cvRound(y0 + 1000 * (a));pt2.x = cvRound(x0 - 1000 * (-b));pt2.y = cvRound(y0 - 1000 * (a));line(linImg, pt1, pt2, Scalar(255, 0, 0), 3, 8, 0);}imshow("lines", linImg);//imwrite("imageText_line.jpg",linImg);if (lines.size() == 3){cout << "found three angels:" << endl;cout << lines[0][1] * 180 / CV_PI << endl << lines[1][1] * 180 / CV_PI << endl << lines[2][1] * 180 / CV_PI << endl << endl;}//Find the proper angel from the three found angelsfloat angel = 0;float piThresh = (float)CV_PI / 90;float pi2 = CV_PI / 2;for (int l = 0; l<numLines; l++){float theta = lines[l][1];if (abs(theta) < piThresh || abs(theta - pi2) < piThresh)continue;else{angel = theta;break;}}//Calculate the rotation angel//The image has to be square,//so that the rotation angel can be calculate rightangel = angel<pi2 ? angel : angel - CV_PI;if (angel != pi2){float angelT = srcImg.rows*tan(angel) / srcImg.cols;angel = atan(angelT);}float angelD = angel * 180 / (float)CV_PI;cout << "the rotation angel to be applied:" << endl << angelD << endl << endl;//Rotate the image to recoverMat rotMat = getRotationMatrix2D(center, angelD, 1.0);Mat dstImg = Mat::ones(srcImg.size(), CV_8UC3);warpAffine(srcImg, dstImg, rotMat, srcImg.size(), 1, 0, Scalar(255, 255, 255));imshow("result", dstImg);//imwrite("imageText_D.jpg",dstImg);waitKey(0);return 0;
}

opencv4x

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgcodecs/legacy/constants_c.h> 
#include <iostream>using namespace cv;
using namespace std;// 二值化阈值
#define GRAY_THRESH 150// 直线上点的个数
#define HOUGH_VOTE 50int main(int argc, char **argv)
{//Read a single-channel imageconst char* filename = argv[1];Mat srcImg = imread(filename, CV_LOAD_IMAGE_GRAYSCALE);if (srcImg.empty())return -1;imshow("source", srcImg);Point center(srcImg.cols / 2, srcImg.rows / 2);//Expand image to an optimal size, for faster processing speed//Set widths of borders in four directions//If borderType==BORDER_CONSTANT, fill the borders with (0,0,0)Mat padded;int opWidth = getOptimalDFTSize(srcImg.rows);int opHeight = getOptimalDFTSize(srcImg.cols);copyMakeBorder(srcImg, padded, 0, opWidth - srcImg.rows, 0, opHeight - srcImg.cols, BORDER_CONSTANT, Scalar::all(0));Mat planes[] = { Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F) };Mat comImg;//Merge into a double-channel imagemerge(planes, 2, comImg);//Use the same image as input and output,//so that the results can fit in Mat welldft(comImg, comImg);//Compute the magnitude//planes[0]=Re(DFT(I)), planes[1]=Im(DFT(I))//magnitude=sqrt(Re^2+Im^2)split(comImg, planes);magnitude(planes[0], planes[1], planes[0]);//Switch to logarithmic scale, for better visual results//M2=log(1+M1)Mat magMat = planes[0];magMat += Scalar::all(1);log(magMat, magMat);//Crop the spectrum//Width and height of magMat should be even, so that they can be divided by 2//-2 is 11111110 in binary system, operator & make sure width and height are always evenmagMat = magMat(Rect(0, 0, magMat.cols & -2, magMat.rows & -2));//Rearrange the quadrants of Fourier image,//so that the origin is at the center of image,//and move the high frequency to the cornersint cx = magMat.cols / 2;int cy = magMat.rows / 2;Mat q0(magMat, Rect(0, 0, cx, cy));Mat q1(magMat, Rect(0, cy, cx, cy));Mat q2(magMat, Rect(cx, cy, cx, cy));Mat q3(magMat, Rect(cx, 0, cx, cy));Mat tmp;q0.copyTo(tmp);q2.copyTo(q0);tmp.copyTo(q2);q1.copyTo(tmp);q3.copyTo(q1);tmp.copyTo(q3);//Normalize the magnitude to [0,1], then to[0,255]//normalize(magMat, magMat, 0, 1, CV_MINMAX);normalize(magMat, magMat, 0, 1, NORM_MINMAX);Mat magImg(magMat.size(), CV_8UC1);magMat.convertTo(magImg, CV_8UC1, 255, 0);imshow("magnitude", magImg);//imwrite("imageText_mag.jpg",magImg);//Turn into binary imagethreshold(magImg, magImg, GRAY_THRESH, 255, cv::THRESH_BINARY);imshow("mag_binary", magImg);//imwrite("imageText_bin.jpg",magImg);//Find lines with Hough Transformationvector<Vec2f> lines;float pi180 = (float)CV_PI / 180;Mat linImg(magImg.size(), CV_8UC3);HoughLines(magImg, lines, 1, pi180, HOUGH_VOTE, 0, 0);int numLines = lines.size();for (int l = 0; l<numLines; l++){float rho = lines[l][0], theta = lines[l][1];Point pt1, pt2;double a = cos(theta), b = sin(theta);double x0 = a*rho, y0 = b*rho;pt1.x = cvRound(x0 + 1000 * (-b));pt1.y = cvRound(y0 + 1000 * (a));pt2.x = cvRound(x0 - 1000 * (-b));pt2.y = cvRound(y0 - 1000 * (a));line(linImg, pt1, pt2, Scalar(255, 0, 0), 3, 8, 0);}imshow("lines", linImg);//imwrite("imageText_line.jpg",linImg);if (lines.size() == 3){cout << "found three angels:" << endl;cout << lines[0][1] * 180 / CV_PI << endl << lines[1][1] * 180 / CV_PI << endl << lines[2][1] * 180 / CV_PI << endl << endl;}//Find the proper angel from the three found angelsfloat angel = 0;float piThresh = (float)CV_PI / 90;float pi2 = CV_PI / 2;for (int l = 0; l<numLines; l++){float theta = lines[l][1];if (abs(theta) < piThresh || abs(theta - pi2) < piThresh)continue;else{angel = theta;break;}}//Calculate the rotation angel//The image has to be square,//so that the rotation angel can be calculate rightangel = angel<pi2 ? angel : angel - CV_PI;if (angel != pi2){float angelT = srcImg.rows*tan(angel) / srcImg.cols;angel = atan(angelT);}//float angelD = angel * 180 / (float)CV_PI;float angelD = angel * 180 / (float)CV_PI;cout << "the rotation angel to be applied: "<< angelD << endl << endl;//Rotate the image to recoverMat rotMat = getRotationMatrix2D(center, angelD, 1.0);Mat dstImg = Mat::ones(srcImg.size(), CV_8UC3);warpAffine(srcImg, dstImg, rotMat, srcImg.size(), 1, 0, Scalar(255, 255, 255));imshow("result", dstImg);imwrite("imageText_D.jpg",dstImg);waitKey(0);return 0;
}

CMakeLists.txt

project( main )
cmake_minimum_required(VERSION 3.10) 
#添加头文件路径
include_directories(/usr/local/include /usr/local/include/opencv4 /usr/local/include/opencv4/opencv2)
#添加库文件路径
link_directories(/usr/local/lib)add_executable(main test.cpp)
target_link_libraries( main -lopencv_core  -lopencv_highgui -lopencv_imgproc -lopencv_imgcodecs)

在这里插入图片描述
在这里插入图片描述

3.四点透视 + 角度 + 旋转

#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;// 直线上点的个数
#define HOUGH_VOTE 50//度数转换
double DegreeTrans(double theta)
{double res = theta / CV_PI * 180;return res;
}//逆时针旋转图像degree角度(原尺寸)    
void rotateImage(Mat src, Mat& img_rotate, double degree)
{//旋转中心为图像中心    Point2f center;center.x = float(src.cols / 2.0);center.y = float(src.rows / 2.0);int length = 0;length = sqrt(src.cols*src.cols + src.rows*src.rows);//计算二维旋转的仿射变换矩阵  Mat M = getRotationMatrix2D(center, degree, 1);warpAffine(src, img_rotate, M, Size(length, length), 1, 0, Scalar(255, 255, 255));//仿射变换,背景色填充为白色  
}//通过霍夫变换计算角度
double CalcDegree(const Mat &srcImage, Mat &dst)
{Mat midImage, dstImage;Canny(srcImage, midImage, 50, 200, 3);cvtColor(midImage, dstImage, CV_GRAY2BGR);//通过霍夫变换检测直线vector<Vec2f> lines;HoughLines(midImage, lines, 1, CV_PI / 180, HOUGH_VOTE);//第5个参数就是阈值,阈值越大,检测精度越高//cout << lines.size() << endl;//由于图像不同,阈值不好设定,因为阈值设定过高导致无法检测直线,阈值过低直线太多,速度很慢//所以根据阈值由大到小设置了三个阈值,如果经过大量试验后,可以固定一个适合的阈值。float sum = 0;//依次画出每条线段for (size_t i = 0; i < lines.size(); i++){float rho = lines[i][0];float theta = lines[i][1];Point pt1, pt2;//cout << theta << endl;double a = cos(theta), b = sin(theta);double x0 = a*rho, y0 = b*rho;pt1.x = cvRound(x0 + 1000 * (-b));pt1.y = cvRound(y0 + 1000 * (a));pt2.x = cvRound(x0 - 1000 * (-b));pt2.y = cvRound(y0 - 1000 * (a));//只选角度最小的作为旋转角度sum += theta;line(dstImage, pt1, pt2, Scalar(55, 100, 195), 1, LINE_AA); //Scalar函数用于调节线段颜色imshow("直线探测效果图", dstImage);}float average = sum / lines.size(); //对所有角度求平均,这样做旋转效果会更好cout << "average theta:" << average << endl;double angle = DegreeTrans(average) - 90;rotateImage(dstImage, dst, angle);//imshow("直线探测效果图2", dstImage);return angle;
}void ImageRecify(const char* pInFileName, const char* pOutFileName)
{double degree;Mat src = imread(pInFileName);imshow("原始图", src);Mat dst;//倾斜角度矫正degree = CalcDegree(src, dst);rotateImage(src, dst, degree);cout << "angle:" << degree << endl;imshow("旋转调整后", dst);Mat resulyImage = dst(Rect(0, 0, dst.cols, 500)); //根据先验知识,估计好文本的长宽,再裁剪下来imshow("裁剪之后", resulyImage);imwrite("recified.jpg", resulyImage);
}int main()
{ImageRecify("31.png", "FinalImage.jpg");waitKey();return 0;
}

opencv4.x

#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;// 直线上点的个数
#define HOUGH_VOTE 50//度数转换
double DegreeTrans(double theta)
{double res = theta / CV_PI * 180;return res;
}//逆时针旋转图像degree角度(原尺寸)    
void rotateImage(Mat src, Mat& img_rotate, double degree)
{//旋转中心为图像中心    Point2f center;center.x = float(src.cols / 2.0);center.y = float(src.rows / 2.0);int length = 0;length = sqrt(src.cols*src.cols + src.rows*src.rows);//计算二维旋转的仿射变换矩阵  Mat M = getRotationMatrix2D(center, degree, 1);warpAffine(src, img_rotate, M, Size(length, length), 1, 0, Scalar(255, 255, 255));//仿射变换,背景色填充为白色  
}//通过霍夫变换计算角度
double CalcDegree(const Mat &srcImage, Mat &dst)
{Mat midImage, dstImage;Canny(srcImage, midImage, 50, 200, 3);cvtColor(midImage, dstImage, COLOR_GRAY2BGR);//通过霍夫变换检测直线vector<Vec2f> lines;HoughLines(midImage, lines, 1, CV_PI / 180, HOUGH_VOTE);//第5个参数就是阈值,阈值越大,检测精度越高//cout << lines.size() << endl;//由于图像不同,阈值不好设定,因为阈值设定过高导致无法检测直线,阈值过低直线太多,速度很慢//所以根据阈值由大到小设置了三个阈值,如果经过大量试验后,可以固定一个适合的阈值。float sum = 0;//依次画出每条线段for (size_t i = 0; i < lines.size(); i++){float rho = lines[i][0];float theta = lines[i][1];Point pt1, pt2;//cout << theta << endl;double a = cos(theta), b = sin(theta);double x0 = a*rho, y0 = b*rho;pt1.x = cvRound(x0 + 1000 * (-b));pt1.y = cvRound(y0 + 1000 * (a));pt2.x = cvRound(x0 - 1000 * (-b));pt2.y = cvRound(y0 - 1000 * (a));//只选角度最小的作为旋转角度sum += theta;line(dstImage, pt1, pt2, Scalar(55, 100, 195), 1, LINE_AA); //Scalar函数用于调节线段颜色imshow("直线探测效果图", dstImage);}float average = sum / lines.size(); //对所有角度求平均,这样做旋转效果会更好cout << "average theta:" << average << endl;double angle = DegreeTrans(average) - 90;rotateImage(dstImage, dst, angle);//imshow("直线探测效果图2", dstImage);return angle;
}void ImageRecify(const char* pInFileName, const char* pOutFileName)
{double degree;Mat src = imread(pInFileName);imshow("原始图", src);Mat dst;//倾斜角度矫正degree = CalcDegree(src, dst);rotateImage(src, dst, degree);cout << "angle:" << degree << endl;imshow("旋转调整后", dst);Mat resulyImage = dst(Rect(0, 0, dst.cols, 1000)); //根据先验知识,估计好文本的长宽,再裁剪下来imshow("裁剪之后", resulyImage);imwrite("recified.jpg", resulyImage);
}int main()
{ImageRecify("test.jpg", "FinalImage.jpg");waitKey();return 0;
}

4.检测矩形轮廓 + 角度 + 旋转

#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
#include <algorithm>bool x_sort(const Point2f & m1, const Point2f & m2)
{return m1.x < m2.x;
}//第一个参数:输入图片名称;第二个参数:输出图片名称
void GetContoursPic(const char* pSrcFileName, const char* pDstFileName)
{Mat srcImg = imread(pSrcFileName);imshow("原始图", srcImg);Mat gray, binImg;//灰度化cvtColor(srcImg, gray, COLOR_RGB2GRAY);imshow("灰度图", gray);//二值化threshold(gray, binImg, 150, 200, CV_THRESH_BINARY);imshow("二值化", binImg);vector<Point>  contours;vector<vector<Point> > f_contours;//注意第5个参数为CV_RETR_EXTERNAL,只检索外框  findContours(binImg, f_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); //找轮廓int max_area = 0;int index;for (int i = 0; i < f_contours.size(); i++){double tmparea = fabs(contourArea(f_contours[i]));if (tmparea > max_area){index = i;max_area = tmparea;}}contours = f_contours[index];CvBox2D rect = minAreaRect(Mat(contours));float angle = rect.angle;cout << "before angle : " << angle << endl;if (angle < -45)angle = (90 + angle);elseangle = -angle;cout << "after angle : " << angle << endl;//新建一个感兴趣的区域图,大小跟原图一样大  Mat RoiSrcImg(srcImg.rows, srcImg.cols, CV_8UC3); //注意这里必须选CV_8UC3RoiSrcImg.setTo(0); //颜色都设置为黑色  //imshow("新建的ROI", RoiSrcImg);//对得到的轮廓填充一下  drawContours(binImg, f_contours, 0, Scalar(255), CV_FILLED);//抠图到RoiSrcImgsrcImg.copyTo(RoiSrcImg, gray);//再显示一下看看,除了感兴趣的区域,其他部分都是黑色的了  namedWindow("RoiSrcImg", 1);imshow("RoiSrcImg", RoiSrcImg);//创建一个旋转后的图像  Mat RatationedImg(RoiSrcImg.rows, RoiSrcImg.cols, CV_8UC1);RatationedImg.setTo(0);//对RoiSrcImg进行旋转  Point2f center = rect.center;  //中心点  Mat M2 = getRotationMatrix2D(center, angle, 1);//计算旋转加缩放的变换矩阵 warpAffine(RoiSrcImg, RatationedImg, M2, RoiSrcImg.size(), 1, 0, Scalar(0));//仿射变换 imshow("旋转之后", RatationedImg);
}void main()
{GetContoursPic("34.png", "FinalImage.jpg");waitKey();
}

opencv4.x

#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <opencv2/imgproc/types_c.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>using namespace cv;
using namespace std;
#include <algorithm>bool x_sort(const Point2f & m1, const Point2f & m2)
{return m1.x < m2.x;
}//第一个参数:输入图片名称;第二个参数:输出图片名称
void GetContoursPic(const char* pSrcFileName, const char* pDstFileName)
{Mat srcImg = imread(pSrcFileName);imshow("原始图", srcImg);Mat gray, binImg;//灰度化cvtColor(srcImg, gray, COLOR_RGB2GRAY);imshow("灰度图", gray);//二值化threshold(gray, binImg, 150, 200, cv::THRESH_BINARY);imshow("二值化", binImg);vector<Point>  contours;vector<vector<Point> > f_contours;//注意第5个参数为CV_RETR_EXTERNAL,只检索外框  findContours(binImg, f_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); //找轮廓int max_area = 0;int index;for (int i = 0; i < f_contours.size(); i++){double tmparea = fabs(contourArea(f_contours[i]));if (tmparea > max_area){index = i;max_area = tmparea;}}contours = f_contours[index];RotatedRect rect = minAreaRect(Mat(contours));float angle = rect.angle;cout << "before angle : " << angle << endl;if (angle < -45)angle = (90 + angle);elseangle = -angle;cout << "after angle : " << angle << endl;//新建一个感兴趣的区域图,大小跟原图一样大  Mat RoiSrcImg(srcImg.rows, srcImg.cols, CV_8UC3); //注意这里必须选CV_8UC3RoiSrcImg.setTo(0); //颜色都设置为黑色  //imshow("新建的ROI", RoiSrcImg);//对得到的轮廓填充一下  drawContours(binImg, f_contours, 0, Scalar(255), cv::FILLED);//抠图到RoiSrcImgsrcImg.copyTo(RoiSrcImg, gray);//再显示一下看看,除了感兴趣的区域,其他部分都是黑色的了  namedWindow("RoiSrcImg", 1);imshow("RoiSrcImg", RoiSrcImg);//创建一个旋转后的图像  Mat RatationedImg(RoiSrcImg.rows, RoiSrcImg.cols, CV_8UC1);RatationedImg.setTo(0);//对RoiSrcImg进行旋转  Point2f center = rect.center;  //中心点  Mat M2 = getRotationMatrix2D(center, angle, 1);//计算旋转加缩放的变换矩阵 warpAffine(RoiSrcImg, RatationedImg, M2, RoiSrcImg.size(), 1, 0, Scalar(0));//仿射变换 imshow("旋转之后", RatationedImg);imwrite("recified.jpg", RatationedImg);
}int main()
{GetContoursPic("test.jpg", "FinalImage.jpg");waitKey();return 0;
}

参考

  • 榴莲小怪兽 opencv-图片矫正
  • OpenCV利用透视变换矫正图像

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LLM架构自注意力机制Transformers architecture Attention is all you need

使用Transformers架构构建大型语言模型显著提高了自然语言任务的性能&#xff0c;超过了之前的RNNs&#xff0c;并导致了再生能力的爆炸。 Transformers架构的力量在于其学习句子中所有单词的相关性和上下文的能力。不仅仅是您在这里看到的&#xff0c;与它的邻居每个词相邻&…

docker的资源控制及数据管理

docker的资源控制及docker数据管理 一.docker的资源控制 1.CPU 资源控制 1.1 资源控制工具 cgroups&#xff0c;是一个非常强大的linux内核工具&#xff0c;他不仅可以限制被 namespace 隔离起来的资源&#xff0c; 还可以为资源设置权重、计算使用量、操控进程启停等等。 …

苍穹外卖 day1 搭建成功环境

引入 idea找不到打包生成的文件目录怎么办&#xff0c;首先点击这个小齿轮 show ecluded files然后就能找到隐藏的文件 这个jar包内含tomcat&#xff0c;可以直接丢在linux上用 开发环境&#xff1a;开发人员在开发阶段使用的环境&#xff0c;一般外部用户无法访问 测试环…

shell脚本之循环语句

循环语句 循环含义 将某代码段重复运行多次&#xff0c;通常有进入循环的条件和退出循环的条件 for循环语句 一般知道循环次数使用for循环 第一类 格式1&#xff1a; for名称 in 取值次数;do;done; 格式2&#xff1a; for 名称 in {取值列表} do done# 打印20次 for i i…

k8s之Pod及Probe 探针机制(健康检查机制)

文章目录 1、Pod1.1、定义1.2、Pod的形式1.2、Pod的使用1.3、 Pod生命周期1.4、生命周期钩子1.5、临时容器1.5.1、定义1.5.2、使用临时容器的步骤 1.6、静态Pod 2、Probe 探针机制&#xff08;健康检查机制&#xff09;2.1、探针分类2.2、Probe配置项2.3、编写yaml测试探针机制…

学C的第三十四天【程序环境和预处理】

相关代码gitee自取&#xff1a; C语言学习日记: 加油努力 (gitee.com) 接上期&#xff1a; 学C的第三十三天【C语言文件操作】_高高的胖子的博客-CSDN博客 1 . 程序的翻译环境和执行环境 在ANSI C(C语言标准)的任何一种实现中&#xff0c;存在两个不同的环境。 &#xff0…

PyTorch学习笔记(十六)——利用GPU训练

一、方式一 网络模型、损失函数、数据&#xff08;包括输入、标注&#xff09; 找到以上三种变量&#xff0c;调用它们的.cuda()&#xff0c;再返回即可 if torch.cuda.is_available():mynn mynn.cuda() if torch.cuda.is_available():loss_function loss_function.cuda(…

1339. 分裂二叉树的最大乘积

链接&#xff1a; ​​​​​​1339. 分裂二叉树的最大乘积 题解&#xff1a; /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* …

Java性能分析中常用命令和工具

当涉及到 Java 性能分析时&#xff0c;有一系列强大的命令和工具可以帮助开发人员分析应用程序的性能瓶颈、内存使用情况和线程问题。以下是一些常用的 Java 性能分析命令和工具&#xff0c;以及它们的详细说明和示例。 以下是一些常用的性能分析命令和工具汇总&#xff1a; …

Nacos配置管理、Feign远程调用、Gateway服务网关

1.Nacos配置管理 1.1.将配置交给Nacos管理的步骤 1.在Nacos中添加配置 Data Id服务名称-环境名称.yaml eg&#xff1a;userservice-dev.yaml 2.引入nacos-config依赖 在user-service服务中&#xff0c;引入nacos-config的客户端依赖 <!--nacos配置管理依赖--> <dep…

redis--主从复制

redis主从复制 Redis 主从复制是一种用于实现数据复制和数据备份的机制&#xff0c;它允许将一个 Redis 服务器的数据复制到其他 Redis 服务器上。主从复制在 Redis 中通常用于构建高可用性架构、读写分离以及数据分析等场景。 主从复制的角色 主服务器&#xff08;Master&a…

系统架构设计专业技能 · 软件工程之需求工程

系列文章目录 系统架构设计高级技能 软件架构概念、架构风格、ABSD、架构复用、DSSA&#xff08;一&#xff09;【系统架构设计师】 系统架构设计高级技能 系统质量属性与架构评估&#xff08;二&#xff09;【系统架构设计师】 系统架构设计高级技能 软件可靠性分析与设计…

Cpp学习——类与对象3

目录 一&#xff0c;初始化列表 1.初始化列表的使用 2.初始化列表的特点 3.必须要使用初始化列表的场景 二&#xff0c;单参数构造函数的隐式类型转换 1.内置类型的隐式类型转换 2. 自定义类型的隐式类型转换 3.多参数构造函数的隐式类型转换 4.当你不想要发生隐式类型转换…

Unity VR:XR Interaction Toolkit 输入系统(Input System):获取手柄的输入

文章目录 &#x1f4d5;教程说明&#x1f4d5;Input System 和 XR Input Subsystem&#xff08;推荐 Input System&#xff09;&#x1f4d5;Input Action Asset⭐Actions Maps⭐Actions⭐Action Properties&#x1f50d;Action Type (Value, Button, Pass through) ⭐Binding …

数据结构<树和二叉树>顺序表存储二叉树实现堆排

✨Blog&#xff1a;&#x1f970;不会敲代码的小张:)&#x1f970; &#x1f251;推荐专栏&#xff1a;C语言&#x1f92a;、Cpp&#x1f636;‍&#x1f32b;️、数据结构初阶&#x1f480; &#x1f4bd;座右铭&#xff1a;“記住&#xff0c;每一天都是一個新的開始&#x1…

Gin+微服务实现抖音视频上传到七牛云

文章目录 安装获取凭证Gin处理微服务处理 如果你对Gin和微服务有一定了解&#xff0c;看本文较容易。 安装 执行命令&#xff1a; go get github.com/qiniu/go-sdk/v7获取凭证 Go SDK 的所有的功能&#xff0c;都需要合法的授权。授权凭证的签算需要七牛账号下的一对有效的A…

Go语言入门指南:基础语法和常用特性解析(上)

一、Go语言前言 Go是一种静态类型的编译语言&#xff0c;常常被称作是21世纪的C语言。Go语言是一个开源项目&#xff0c;可以免费获取编译器、库、配套工具的源代码&#xff0c;也是高性能服务器和应用程序的热门选择。 Go语言可以运行在类UNIX系统——比如Linux、OpenBSD、M…

Python批量爬虫下载文件——把Excel中的超链接快速变成网址

本文的背景是&#xff1a;大学关系很好的老师问我能不能把Excel中1000个超链接网址对应的pdf文档下载下来。虽然可以手动一个一个点击下载&#xff0c;但是这样太费人力和时间了。我想起了之前的爬虫经验&#xff0c;给老师分析了一下可行性&#xff0c;就动手实践了。    没…

Platypus:Quick,Cheap,and Powerful Refinement of LLMs

Platypus:Quick,Cheap,and Powerful Refinement of LLMs IntroductionMethod2.1 Curating Open- PlatypusRemoving similar&duplicate questionsContamination CheckFine-tuning & mergingResult参考Introduction 现在大模型已经取得很不错的结果,如何把大模型的能…

sh 脚本循环语句和正则表达式

目录 1、循环语句 1、for 2、while 3、until 2、正则表达式 1、元字符 2、表示次数 3、位置锚定 4、分组 5、扩展正则表达式 1、循环语句 循环含义 将某代码段重复运行多次&#xff0c;通常有进入循环的条件和退出循环的条件 重复运行次数 循环次数事先已知 循环次…