从图片识别到方框并且截取出来,以下是全部代码:

// hkOpenCVtest.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <opencv2\opencv.hpp>
#include <opencv2\highgui.hpp>
//#include <opencv\opencv.hpp>
#include <opencv2\imgproc.hpp>
#include <io.h>#define  GREY  0
#define  COLOR 1
#pragma warning(disable : 4996)
using namespace std;
using namespace cv;//#define  DEBUGP
//文件的路径,也可以使用cin自己指定,例如cin>>path
char * filePath = "D:\\workspace\\hkjpg\\002";string outPutPath = "D:\\workspace\\hkjpg\\003";std::map<int, std::set<int>> generateBorders(const std::vector<cv::Point> & vecPts)
{std::map<int, std::set<int>> borders;cv::Point tl(vecPts[0]), tr(vecPts[1]), bl(vecPts[2]), br(vecPts[3]);// tl to trdouble K = double(tl.y - tr.y) / (tl.x - tr.x);for (int i = tl.x; i < tr.x; ++i)borders[i].insert(cvRound(-K*(tl.x - i) + tl.y));// tr to brif (tr.x != br.x){K = double(tr.y - br.y) / (tr.x - br.x);for (int i = tr.x; i < br.x; ++i)borders[i].insert(cvRound(-K*(tr.x - i) + tr.y));}// br to blK = double(br.y - bl.y) / (br.x - bl.x);for (int i = bl.x; i < br.x; ++i)borders[i].insert(cvRound(-K*(br.x - i) + br.y));// bl to tlif (bl.x != tl.x){K = double(bl.y - tl.y) / (bl.x - tl.x);for (int i = tl.x; i < bl.x; ++i)borders[i].insert(cvRound(-K*(bl.x - i) + bl.y));}for (auto it = borders.begin(); it != borders.end(); ++it){if ((*it).second.size() == 2)continue;std::set<int> newone = { *(*it).second.begin(), *(--(*it).second.end()) };(*it).second.swap(newone);}#ifdef DEBUG_CODEcv::Mat disp = cv::imread("1111.PNG", CV_LOAD_IMAGE_COLOR);for (auto it = borders.begin(); it != borders.end(); ++it){cv::circle(disp, cv::Point((*it).first, *(*it).second.begin()), 1, cv::Scalar(255, 255, 0), -1);cv::circle(disp, cv::Point((*it).first, *(--(*it).second.end())), 1, cv::Scalar(0, 255, 255), -1);}cv::circle(disp, tl, 2, cv::Scalar(0, 0, 255), -1);cv::circle(disp, tr, 2, cv::Scalar(0, 0, 255), -1);cv::circle(disp, bl, 2, cv::Scalar(0, 0, 255), -1);cv::circle(disp, br, 2, cv::Scalar(0, 0, 255), -1);
#endif // DEBUG_CODEreturn borders;
}cv::Mat generateMask(const cv::Mat & src, const std::vector<cv::Point> & vecPts)
{cv::Mat mask = cv::Mat::zeros(src.size(), CV_8UC1);cv::Point tl(vecPts[0]), tr(vecPts[1]), bl(vecPts[2]), br(vecPts[3]);std::map<int, std::set<int>> borders = generateBorders(vecPts);int minX = std::min(tl.x, bl.x),maxX = std::max(tr.x, br.x),minY = std::min(tl.y, tr.y),maxY = std::max(bl.y, br.y);uchar minZ = std::min(src.at<uchar>(tl), src.at<uchar>(tr));minZ = std::min(minZ, src.at<uchar>(bl));minZ = std::min(minZ, src.at<uchar>(br));for (size_t j = minY; j < maxY; ++j){const uchar* pS = src.ptr<uchar>(j);uchar* pM = mask.ptr<uchar>(j);for (size_t i = minX; i < maxX; ++i){// in the region.if (*borders[i].begin() < j && j < *(++borders[i].begin())){pM[i] = pS[i];}}}return mask;}void rotate_arbitrarily_angle(Mat &src, Mat &dst, float angle)
{float radian = (float)(angle / 180.0 * CV_PI);//填充图像int maxBorder = (int)(max(src.cols, src.rows)* 1.414); //即为sqrt(2)*maxint dx = (maxBorder - src.cols) / 2;int dy = (maxBorder - src.rows) / 2;copyMakeBorder(src, dst, dy, dy, dx, dx, BORDER_CONSTANT);//旋转Point2f center((float)(dst.cols / 2), (float)(dst.rows / 2));Mat affine_matrix = getRotationMatrix2D(center, angle, 1.0);//求得旋转矩阵warpAffine(dst, dst, affine_matrix, dst.size());//计算图像旋转之后包含图像的最大的矩形float sinVal = abs(sin(radian));float cosVal = abs(cos(radian));Size targetSize((int)(src.cols * cosVal + src.rows * sinVal),(int)(src.cols * sinVal + src.rows * cosVal));//剪掉多余边框int x = (dst.cols - targetSize.width) / 2;int y = (dst.rows - targetSize.height) / 2;Rect rect(x, y, targetSize.width, targetSize.height);dst = Mat(dst, rect);
}// 获取指定像素点放射变换后的新的坐标位置
CvPoint getPointAffinedPos(CvPoint src, int h, int w, double degree)
{int diaLength = int(sqrt((h*h + w*w)));Point center;center.x = center.y = diaLength / 2;src.x += diaLength / 2 - w / 2;src.y += diaLength / 2 - h / 2;double angle = degree * CV_PI / 180.0;CvPoint dst;int x = src.x - center.x;int y = src.y - center.y;dst.x = cvRound(x * cos(angle) + y * sin(angle) + center.x);dst.y = cvRound(-x * sin(angle) + y * cos(angle) + center.y);return dst;
}
void GetImageRect(IplImage* orgImage, CvRect rectInImage, IplImage* imgRect)
{//从图像orgImage中提取一块(rectInImage)子图像imgRectIplImage *result = imgRect;CvSize size;size.width = rectInImage.width;size.height = rectInImage.height;//result=cvCreateImage( size, orgImage->depth, orgImage->nChannels );//从图像中提取子图像cvSetImageROI(orgImage, rectInImage);cvCopy(orgImage, result);cvResetImageROI(orgImage);
}void getFiles(string path, vector<string>& files)
{//文件句柄  long long   hFile = 0;//文件信息  struct _finddata_t fileinfo;memset(&fileinfo, 0, sizeof(fileinfo));string p;if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1){do{//如果是目录,迭代之  //如果不是,加入列表  if ((fileinfo.attrib &  _A_SUBDIR)){if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)getFiles(p.assign(path).append("\\").append(fileinfo.name), files);}else{//如果是文件的化,放进来,这个加了路径名的path的命名files.push_back(p.assign(path).append("\\").append(fileinfo.name));}memset(&fileinfo, 0, sizeof(fileinfo));} while (_findnext(hFile, &fileinfo) == 0);_findclose(hFile);}
}bool picSegment(Mat &ResizeImg, int type, int n, int threshhold = 1)
{Mat BinRGBImg;if (!type){//灰度变换Mat gray;cvtColor(ResizeImg, gray, COLOR_BGR2GRAY);threshold(gray, BinRGBImg, 100, 255, THRESH_BINARY_INV);
#ifdef DEBUGPimshow("灰度阈值图", gray);
#endif}else{//基于颜色信息二值化unsigned char pixelB, pixelG, pixelR;  //记录各通道值unsigned char DifMax = 60;             //基于颜色区分的阈值设置unsigned char B = 25, G = 25, R = 25;if (1 == threshhold){DifMax = 60;             //基于颜色区分的阈值设置B = 25;G = 25;R = 25; //各通道的阈值设定,}else if (2 == threshhold){DifMax = 100;//基于颜色区分的阈值设置B = 40;G = 98;R = 8; //各通道的阈值设定,}BinRGBImg = ResizeImg.clone();  //二值化之后的图像for (int i = 0; i < ResizeImg.rows; i++)   //通过颜色分量将图片进行二值化处理{for (int j = 0; j < ResizeImg.cols; j++){pixelB = ResizeImg.at<Vec3b>(i, j)[0]; //获取图片各个通道的值pixelG = ResizeImg.at<Vec3b>(i, j)[1];pixelR = ResizeImg.at<Vec3b>(i, j)[2];if (abs(pixelB - B) < DifMax && abs(pixelG - G) < DifMax && abs(pixelR - R) < DifMax){                                           //将各个通道的值和各个通道阈值进行比较BinRGBImg.at<Vec3b>(i, j)[0] = 255;     //符合颜色阈值范围内的设置成白色BinRGBImg.at<Vec3b>(i, j)[1] = 255;BinRGBImg.at<Vec3b>(i, j)[2] = 255;}else{BinRGBImg.at<Vec3b>(i, j)[0] = 0;        //不符合颜色阈值范围内的设置为黑色BinRGBImg.at<Vec3b>(i, j)[1] = 0;BinRGBImg.at<Vec3b>(i, j)[2] = 0;}}}
#ifdef DEBUGPimshow("基于颜色信息二值化", BinRGBImg);        //显示二值化处理之后的图像cvWaitKey(0);
#endif}////----------------------------Mat BinOriImg;     //形态学处理结果图像if (type){Mat element = getStructuringElement(MORPH_RECT, Size(3, 3)); //设置形态学处理窗的大小dilate(BinRGBImg, BinOriImg, element);     //进行多次膨胀操作dilate(BinOriImg, BinOriImg, element);dilate(BinOriImg, BinOriImg, element);erode(BinOriImg, BinOriImg, element);      //进行多次腐蚀操作erode(BinOriImg, BinOriImg, element);erode(BinOriImg, BinOriImg, element);
#ifdef DEBUGPimshow("形态学处理后", BinOriImg);        //显示形态学处理之后的图像cvWaitKey(0);
#endifcvtColor(BinOriImg, BinOriImg, CV_BGR2GRAY);   //将形态学处理之后的图像转化为灰度图像threshold(BinOriImg, BinOriImg, 100, 255, THRESH_BINARY); //灰度图像二值化}else{Mat element = getStructuringElement(MORPH_RECT, Size(3, 3)); //设置形态学处理窗的大小dilate(BinRGBImg, BinOriImg, element);     //进行多次膨胀操作//dilate(BinOriImg, BinOriImg, element);//dilate(BinOriImg, BinOriImg, element);erode(BinOriImg, BinOriImg, element);      //进行多次腐蚀操作//erode(BinOriImg, BinOriImg, element);//erode(BinOriImg, BinOriImg, element);
#ifdef DEBUGPimshow("形态学处理后", BinOriImg);        //显示形态学处理之后的图像cvWaitKey(0);
#endif}//--------------------------------------double length, area, rectArea;     //定义轮廓周长、面积、外界矩形面积double rectDegree = 0.0;           //矩形度=外界矩形面积/轮廓面积double long2Short = 0.0;           //体态比=长边/短边CvRect rect;           //外界矩形CvBox2D box, boxTemp;  //外接矩形CvPoint2D32f pt[4];    //矩形定点变量double axisLong = 0.0, axisShort = 0.0;        //矩形的长边和短边double axisLongTemp = 0.0, axisShortTemp = 0.0;//矩形的长边和短边double LengthTemp;     //中间变量float  angle = 0;      //记录车牌的倾斜角度float  angleTemp = 0;bool   TestPlantFlag = 0;  //车牌检测成功标志位CvMemStorage *storage = cvCreateMemStorage(0);CvSeq * seq = 0;     //创建一个序列,CvSeq本身就是一个可以增长的序列,不是固定的序列CvSeq * tempSeq = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint), storage);int cnt = cvFindContours(&(IplImage(BinOriImg)), storage, &seq, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);//第一个参数是IplImage指针类型,将MAT强制转换为IplImage指针类型//返回轮廓的数目 //获取二值图像中轮廓的个数cout << "number of contours   " << cnt << endl;  //打印轮廓个数for (tempSeq = seq; tempSeq != NULL; tempSeq = tempSeq->h_next){length = cvArcLength(tempSeq);       //获取轮廓周长area = cvContourArea(tempSeq);       //获取轮廓面积printf("周长=%f,面积=%f\n", length, area);//if ((area > 1500 && area < 8000) && (length > 100) && (length < 300))     //矩形区域面积大小判断if ((area > 5000 && area < 8000) && (length < 500)){rect = cvBoundingRect(tempSeq, 1);//计算矩形边界boxTemp = cvMinAreaRect2(tempSeq, 0);  //获取轮廓的矩形cvBoxPoints(boxTemp, pt);              //获取矩形四个顶点坐标angleTemp = boxTemp.angle;                 //得到倾斜角度printf("x=%f,y=%f\n", pt[0].x, pt[0].y);//if ((pt[0].x > 200)&&((pt[0].x < 400))){axisLongTemp = sqrt(pow(pt[1].x - pt[0].x, 2) + pow(pt[1].y - pt[0].y, 2));  //计算长轴(勾股定理)axisShortTemp = sqrt(pow(pt[2].x - pt[1].x, 2) + pow(pt[2].y - pt[1].y, 2)); //计算短轴(勾股定理)if (axisShortTemp > axisLongTemp)   //短轴大于长轴,交换数据{LengthTemp = axisLongTemp;axisLongTemp = axisShortTemp;axisShortTemp = LengthTemp;}elseangleTemp += 90;rectArea = axisLongTemp * axisShortTemp;  //计算矩形的面积rectDegree = area / rectArea;     //计算矩形度(比值越接近1说明越接近矩形)long2Short = axisLongTemp / axisShortTemp; //计算长宽比//if (long2Short > 2.2 && long2Short < 3.8 && rectDegree > 0.63 && rectDegree < 1.37 && rectArea > 2000 && rectArea < 50000){Mat GuiRGBImg = ResizeImg.clone();TestPlantFlag = true;             //检测车牌区域成功for (int i = 0; i < 4; ++i)       //划线框出车牌区域cvLine(&(IplImage(GuiRGBImg)), cvPointFrom32f(pt[i]), cvPointFrom32f(pt[((i + 1) % 4) ? (i + 1) : 0]), CV_RGB(255, 0, 0));
#ifdef DEBUGPimshow("提取结果图", GuiRGBImg);    //显示最终结果图cvWaitKey(0);
#endifMat mask, dst,rot;vector<vector<Point>> contour;std::vector<cv::Point>  pts;mask = Mat::zeros(GuiRGBImg.size(), CV_8U);for (int i = 0; i < 4; ++i){Point p;p.x = pt[i].x;p.y = pt[i].y;pts.push_back(p);}//Mat genMat = generateMask(GuiRGBImg, vecPts);contour.push_back(pts);drawContours(mask, contour, 0, Scalar::all(255), -1);GuiRGBImg.copyTo(dst, mask);rotate_arbitrarily_angle(dst, rot, angleTemp);/*imshow("mask", dst);cvWaitKey(0);*///imshow("rot", rot);//cvWaitKey(0);/*CvPoint tmpPt;tmpPt.x = rect.x;tmpPt.y = rect.y;CvPoint topLeft = getPointAffinedPos(tmpPt, rect.height, rect.width, angleTemp);*/box = boxTemp;angle = angleTemp;axisLong = axisLongTemp;axisShort = axisShortTemp;cout << "倾斜角度:" << angle << endl;//Sleep(10 * 1000);//cv::destroyWindow("提取结果图");//Mat roi = GuiRGBImg(Rect(pt[1].x,  pt[1].y, pt[3].x - pt[1].x, pt[1].y - pt[0].y));int xmin = 2000;int ymin = 2000;int xmax = 0;int ymax = 0;int pos1 = 0;int pos2 = 0;int pos3 = 0;int pos4 = 0;for (int i = 0; i < 3; i++){if (xmin > pt[i].x){xmin = pt[i].x;pos1 = i;}if (xmax < pt[i].x){xmax = pt[i].x;pos4 = i;}}for (int i = 0; i < 3; i++){if (ymin > pt[i].y){ymin = pt[i].y;}if (ymax < pt[i].y){ymax = pt[i].y;}}//Mat roi = GuiRGBImg(Rect(pt[1].x, pt[1].y, 85, 70));topLeftMat roi = GuiRGBImg(Rect(xmin , ymin , 85, 70));//Mat roi = GuiRGBImg(Rect(xmin, ymin, xmax-xmin, ymax-ymin));//提取的关键就是Rect(0,0,30,30),其中0 ,0表示感兴趣区域的左上角位置,后面的30,30表示感兴趣部分的宽度和高度Mat img1;roi.copyTo(img1);//将感兴趣区域赋值到img1;Mat ResizeImg, RotationImg;Point2f RPt(320, 320);resize(img1, ResizeImg, Size(640, 640 * img1.rows / img1.cols));rotate_arbitrarily_angle(ResizeImg, RotationImg, angle);Mat sc1, dc2;//cvCopy(&sc1,&dc2, &boxTemp);//GetImageRect(IplImage* orgImage, CvRect rectInImage, IplImage* imgRect)
#ifdef DEBUGP/*imshow("cvCopy", dc2);cvWaitKey(0);*/
#endif//RotationImg = getRotationMatrix2D(RPt, angle, 1);
#ifdef DEBUGP/*imshow("getRotationMatrix2D", RotationImg);cvWaitKey(0);*/
#endif//定义保存图像的完整路径char strSaveName[20] = { 0 };sprintf(strSaveName, "0000%d", n);string strImgSavePath = outPutPath + "\\" + strSaveName;//定义保存图像的格式strImgSavePath += ".jpg";//strImgSavePath += ".png";//保存操作imwrite(strImgSavePath.c_str(), RotationImg);//namedWindow("gag", 1);
#ifdef DEBUGPimshow("gag", ResizeImg);cvWaitKey(0);
#endifreturn true;//IplImage *image=NULL;将ROI区域图像保存在image中:左上角x、左上角y、矩形长、宽//cvSetImageROI(&(IplImage(GuiRGBImg)), cvRect(pt[0].x, pt[0].y, axisLong, axisShort));//cvShowImage("imageROI", &(IplImage(GuiRGBImg)));执行cvSetImageROI()之后显示image图像是只显示ROI标识的一部分,即改变了指针image,但是它仍旧保留有原来图像的信息,在执行这一句cvResetImageROI(image),之后,image指示原来的图像信息。cvResetImageROI(image);cvShowImage("image2", image);//cvWaitKey(0);}}}}return false;
}int main(int argc, const char * argv[])
{//string file_path;vector<string> files;getFiles(filePath, files);int size = files.size();for (int i = 0; i < size; i++){string picname = files[i];Mat OriginalImg;OriginalImg = imread(picname, IMREAD_COLOR);//读取原始彩色图像//OriginalImg = imread("E:\\workspace\\1-MyWork\\2-巡逻机器人资料汇总\\src\\CH-HCNetSDKV6.1.4.6_build20191220_Win64\\hkOpencv\\hkOpenCVtest\\x64\\Release\\002.jpg", IMREAD_COLOR);//读取原始彩色图像if (OriginalImg.empty())  //判断图像对否读取成功{cout << "错误!读取图像失败\n";return -1;}//imshow("原图", OriginalImg); //显示原始图像//cvWaitKey(0);cout << "Width:" << OriginalImg.rows << "\tHeight:" << OriginalImg.cols << endl;//打印图像长宽Mat ResizeImg;if (OriginalImg.cols > 640)resize(OriginalImg, ResizeImg, Size(640, 640 * OriginalImg.rows / OriginalImg.cols));//imshow("尺寸变换图", ResizeImg);//cvWaitKey(0);if (!picSegment(ResizeImg, GREY, i, 0)){if (!picSegment(ResizeImg, COLOR, i, 1)){picSegment(ResizeImg, COLOR, i, 2);}}// insert code here...//Mat Imags = imread("D:\\workspace\\hkjpg\\002\\1590649791.jpg");//读取图片//imshow("source", Imags);//显示图片在 名为"source"的窗口里//Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));//获得用来腐蚀的内核矩阵//Mat Imags2;//用来存放腐蚀之后的图片//erode(Imags, Imags2, element);//进行腐蚀操作//imshow("target", Imags2);//显示图片 在名为"target"的窗口里//cvWaitKey(0);//等待按键操作再执行后续 按随意键将进行下一步 return 程序结束}//forreturn 0;
}


效果不是很好,准确率80%左右

opencv应用海康案例-拍照并识别方框相关推荐

  1. (一)Qt+OpenCV调用海康工业相机SDK示例开发

    系列文章目录 提示:这里是该系列文章的所有文章的目录 第一章: (一)Qt+OpenCV调用海康工业相机SDK示例开发 第二章: (二)Qt多线程实现海康工业相机图像实时采集 文章目录 系列文章目录 ...

  2. pyQT5 学习使用 笔记 六 pyQt5+opencv 显示海康GIGE相机动态视频流

    opencv 读取 海康GIGE相机视频流 新项目中我们需要使用opencv读取海康威视的工业相机 MV-CA060-10GM 的视频流进行处理.那么首先我们要读取到相机的视频流,总所周知 openc ...

  3. ubuntu 使用opencv 获取海康网络摄像头视频流

    1. 前言 之前在windows平台下使用opencv获取海康网络摄像头的视频流,但是不管怎么设置都无法登录摄像头,导致无法获取摄像头的视频流,但是换到ubuntu又正常了,主要是设置rtsp的格式, ...

  4. QT+opencv调用海康工业相机

    这里写自定义目录标题 QT+opencv调用海康工业相机 开发环境 引用海康开发文件 直接上代码 QT+opencv调用海康工业相机 最近在使用Opencv调用海康工业相机的程序,从网上查了好多资料, ...

  5. Emgucv不完整图像分割试验(十八)——Emgucv或opencv连接海康/萤石网络4G摄像头

    项目需要远程连摄像头,之前也一直觉得这事挺简单的,opencv有教程也平时很多地方见过这样的操作,没想到实践起来蛮多坑的. 1.首先确定摄像头支不支持4G或WIFI,尽量选海康萤石这种大厂,资料较多. ...

  6. 海康威视工业相机SDK二次开发(VS+Opencv+QT+海康SDK+C++)(一)

    最近在做一个项目,涉及到工业相机,需要对其进行二次开发.相机方面选择了海康威视,网上关于海康威视工业相机SDK的开发资料很少,官方文档里面虽然写的是支持C++开发的,但其实是C.自己也摸索了一段时间, ...

  7. 海康监控系统行为识别服务器,基于海康视频监控系统的目标检测和跟踪

    摘要: 随着人民生活质量的迅速提高,工业生产.家居生活服务.公共场所等各个领域的正常工作都要求智能视频监控系统的协助,并且对于智能监控系统的性能要求也越来越高.所谓智能视频监控系统就是指在不需要人为帮 ...

  8. Python调用海康SDK进行车牌识别(动态链接库的方法—不通过swig)

    由于公司项目需要,要通过Python取得海康相机识别到的车牌号,由于目前在办公室,无法进行实际测试,所以通过网络触发抓拍的方式来进行. 首先要下载海康官网的SDK示例,最开始从网上查找资料是通过swi ...

  9. 海康工业相机拍照存图控制台demo

    #include <stdio.h> #include <Windows.h> #include <process.h> #include <conio.h& ...

最新文章

  1. 对Excel表的查询、插入和更新操作
  2. 他入狱10年自学数学,如今凭借手稿发了篇论文,被同行评价“足以开辟数论新领域”...
  3. [转]Git忽略提交规则 - .gitignore配置运维总结
  4. Codechef:Path Triples On Tree
  5. 前后端、多语言、跨云部署,全链路追踪到底有多难?
  6. OpenCv之Canny边界检测(笔记13)
  7. linux性能测试工具的记录
  8. matlab dpabi安装,Android 8 应用安装时 ABI 确认过程
  9. JS任务栏滚动效果问题
  10. [转载] hexo categories和tags页面不显示解决办法
  11. Maple 教程 何青,科学出版社
  12. 一个计算机软件学生的求职简历,计算机学生求职的个人简历模板
  13. 计算机组装故障排除方法,计算机的硬件组装及故障排除
  14. 哈工大车万翔教授:NLPer的核心竞争力是什么?
  15. vimgrep 查找光标下单词并打开quickfix
  16. 华科计算机学院三好学生,2015-2016年度本科生国奖国励校三好奖学金评选细则(含加分项)...
  17. 国外android逆向的论坛,初探android逆向
  18. 破解蛋白质结构秘密的AlphaFold
  19. SwiftUI Swift 内功之如何在 Swift 中进行自动三角函数计算
  20. 多合一音乐搜索器项目源码分享,支持播放,下载

热门文章

  1. Busybox DHCP数据结构
  2. 两年经验斩获蚂蚁/头条 Offer,牛逼了
  3. 解决php echo中文乱码
  4. 首次揭秘年薪40万Java开发在阿里巴巴是什么水平?
  5. idea使用本地代码远程调试线上运行代码---linux环境
  6. 用ps把图片变成素描画
  7. 解锁iphone的ID图文教程
  8. 乐视界短视频直播助农,公益正能量传递!
  9. 大量企业取消微信办公,只因数据泄露屡禁不止
  10. 智能感知 不正常的解决方法