最近项目需要用到美颜的一些效果,因此开始接触opencv 计算机视觉库,在腾讯课堂上找到一个简单且免费的入门视频《Opencv4 快速入门视频30讲》,看完视频后,初步才对opencv 有一个比较清晰的概念和基本用法。 接下来就是开始对美颜的一些初步接触,下面写的一个简单的测试 效果,具体功能包括亮度、对比度、瘦脸、大眼、美白磨皮等,但实际上用于项目使用还是问题很多,需要更多的优化。

1.图像创建各个功能滑动条

void BeautyCam::initMainImgUI()
{namedWindow("BeautyCam", WINDOW_AUTOSIZE);string path = "6.jpg";m_MainImg =imread(path);imshow("src", m_MainImg);//检测人脸数据68点m_vecFaceData = dectectFace68(path);int max_value = 100;int con_value = 100;int lignhtnesss = 50;int contrast = 2;int bigeyeval = 0;int faceval = 0;int beautyval = 0;createTrackbar("亮度", "BeautyCam", &lignhtnesss, max_value, on_lightness, (void*)(&m_MainImg));createTrackbar("对比度", "BeautyCam", &contrast, max_value, on_contrast, (void*)(&m_MainImg));createTrackbar("大眼", "BeautyCam", &bigeyeval, 60, on_BigEye, (void*)(&m_MainImg));createTrackbar("瘦脸", "BeautyCam", &faceval, 70, on_thinFace, (void*)(&m_MainImg));createTrackbar("美颜", "BeautyCam", &beautyval, 200, on_beautyFace, (void*)(&m_MainImg));on_lightness(50, (void*)(&m_MainImg));imshow("BeautyCam", m_MainImg);
}

此代码就是创建滚动条的初始化程序,主要就是createTrackbar函数的使用:

原型:

CV_EXPORTS int createTrackbar(const String& trackbarname,  //滚动条名称

const String& winname, //滚动条作用在哪一个窗口上 窗口名称
                    int* value, int count,  //滑块初始值  和 滚动条最大值
                    TrackbarCallback onChange = 0, // 回调函数  滑条值变化
                    void* userdata = 0); //用户创给回调函数的用户数据

这里就是需要定义相关的回调函数,原型为:void (*TrackbarCallback)(int pos, void* userdata);

因此只需要创建相同的函数就行,滑条的变化就会导致回调函数触发,传递形参pos值的变化。

例如:

    //对比度调节static void on_contrast(int b, void*userdata);//亮度调节static void on_lightness(int b, void*userdata);//眼睛调节static void on_BigEye(int b, void*userdata);//瘦脸效果static void on_thinFace(int b, void*userdata);//美颜效果static void on_beautyFace(int b, void*userdata);

2.回调函数 对比度调节的实现

void BeautyCam::on_contrast(int b, void*userdata)
{Mat img = *((Mat *)userdata);Mat m = Mat::zeros(img.size(), img.type());Mat dst = Mat::zeros(img.size(), img.type());m = Scalar(b, b, b);double con = b / 100.0;addWeighted(img, con, m, 0, 0, dst);imshow("BeautyCam", dst);
}

addWeighted()函数是将两张相同大小,相同类型的图片融合的函数;

原型:CV_EXPORTS_W void addWeighted(InputArray src1, //第一个输入图像

double alpha, //第一个元素权重

InputArray src2, //第二个输入图像
                              double beta, // 第二个元素权重

double gamma, //图1和图2 作和后添加的数值

OutputArray dst,//输出图像

int dtype = -1);

3. 回调函数 亮度调节的实现

void BeautyCam::on_lightness(int b, void*userdata)
{Mat img = *((Mat *)userdata);Mat m = Mat::zeros(img.size(), img.type());Mat dst = Mat::zeros(img.size(), img.type());m = Scalar(b, b, b);addWeighted(img, 1.0, m, 0, b, dst); imshow("BeautyCam", dst);
}

同上,对比度和亮度其实可以直接用一个addWeighted  实现,同时设置亮度和对比度(差值在扩大),主要是就是对addWeighed 的beta 和alpha参数去调节。

4.人脸数据检测

需要实现大眼或者瘦脸的效果,首先是需要检测人脸并提取特征点,一般常用的就是68个点,如下:

在此处是通过调用三方库dlib来获取68点特性点数据的:

std::vector<std::vector<Point2f>> BeautyCam::dectectFace68(const string &path)
{std::vector<std::vector<Point2f>>  rets;//加载图片路径array2d<rgb_pixel> img;load_image(img, path.c_str());//定义人脸检测器frontal_face_detector detector = get_frontal_face_detector();std::vector<dlib::rectangle> dets = detector(img);for (auto var : dets){//关键点检测器shape_predictor sp;deserialize("shape_predictor_68_face_landmarks.dat") >> sp;//定义shape对象保存检测的68个关键点full_object_detection shape = sp(img, var);//存储文件ofstream out("face_detector.txt");//读取关键点到容器中std::vector<Point2f> points_vec;for (int i = 0; i < shape.num_parts(); ++i){auto a = shape.part(i);out << a.x() << " " << a.y() << " ";Point2f ff(a.x(), a.y());points_vec.push_back(ff);}rets.push_back(points_vec);}cout << "人脸检测结束:" <<dets.size()<<"张人脸数据"<< endl;return rets;
}

5.图像平移变形算法

接下来的难题就是图像局部变形算法,具体原理就是瘦脸是使用图像局部平移变形,放大眼睛是图像局部缩放变形。

图像局部平移变形公式:

说实话我看着这个公式看不懂,好像是结合《Interactive Image Warping》交互式图像变形算法而来的,去查看此文章过程中,发现全英文的,只能说一句,干瞪眼,完全看不懂,更别说公式是怎么推导出来的了,放弃了,直接根据大佬的代码去看懂这个公式。

参考:https://blog.csdn.net/grafx/article/details/70232797  图像处理算法之瘦脸及放大眼睛

图像局部缩放公式(大眼):

参考:https://www.freesion.com/article/40151105562/   瘦脸大眼算法

百度过程中并没有发现c++编写的一些瘦脸大眼测试例子,有些贴的代码比较简单参数有点不好理解,但是python却有相关的例子(原理一样 ),因此通过python代码去封装成c++ 能使用的接口。

瘦脸和大眼主要是参考如下两篇博客来封装的函数接口:

参考:https://www.cnblogs.com/ckAng/p/10978078.html  python+opencv+dlib瘦脸效果

参考:https://www.freesion.com/article/40151105562/   瘦脸大眼算法

6.回调函数 大眼效果调节

void BeautyCam::on_BigEye(int b, void*userdata)
{Mat src = *((Mat *)userdata);Mat dst = src.clone();for (auto points_vec : m_pIntance->m_vecFaceData){Point2f left_landmark = points_vec[38];Point2f  left_landmark_down = points_vec[27];Point2f    right_landmark = points_vec[44];Point2f    right_landmark_down = points_vec[27];Point2f   endPt = points_vec[30];//# 计算第4个点到第6个点的距离作为距离/*float r_left = sqrt((left_landmark.x - left_landmark_down.x) * (left_landmark.x - left_landmark_down.x) +(left_landmark.y - left_landmark_down.y) * (left_landmark.y - left_landmark_down.y));cout << "左眼距离:" << r_left;*/float r_left = b;//  # 计算第14个点到第16个点的距离作为距离//float   r_right = sqrt(//  (right_landmark.x - right_landmark_down.x) * (right_landmark.x - right_landmark_down.x) +//    (right_landmark.y - right_landmark_down.y) * (right_landmark.y - right_landmark_down.y));//cout << "右眼距离:" << r_right;float r_right = b;//   # 瘦左                     m_pIntance->LocalTranslationWarp_Eye(src, dst, left_landmark.x, left_landmark.y, endPt.x, endPt.y, r_left);//   # 瘦右m_pIntance->LocalTranslationWarp_Eye(src, dst, right_landmark.x, right_landmark.y, endPt.x, endPt.y, r_right);}imshow("BeautyCam", dst);
}

对于眼睛的放大,主要是对特征点38 27 44 30 四个点来进行图像局部缩放,也可以自己找适当的点尝试,点并不是唯一的。

此处用作滑条调节,因此把左眼距离和右眼距离都设置成滑条值,但这样是有问题的,因为不是每对眼睛拍照的眼珠都是一样大的。因此可以直接根据计算的距离(代码注释的地方)来进行加减滑条值。

例如:r_right = (系数)*r_right + b  r_left= (系数)*r_left+ b     需要自己去调节适当的系数

图像局部缩放算法代码实现:

void BeautyCam::LocalTranslationWarp_Eye(Mat &img, Mat &dst, int warpX, int warpY, int endX, int endY, float radius)
{//平移距离 float ddradius = radius * radius;//计算|m-c|^2size_t mc = (endX - warpX)*(endX - warpX) + (endY - warpY)*(endY - warpY);//计算 图像的高  宽 通道数量int height = img.rows;int width = img.cols;int chan = img.channels();auto Abs = [&](float f) {return f > 0 ? f : -f;};for (int i = 0; i < width; i++){for (int j = 0; j < height; j++){// # 计算该点是否在形变圆的范围之内//# 优化,第一步,直接判断是会在(startX, startY)的矩阵框中if ((Abs(i - warpX) > radius) && (Abs(j - warpY) > radius))continue;float distance = (i - warpX)*(i - warpX) + (j - warpY)*(j - warpY);if (distance < ddradius){float rnorm = sqrt(distance) / radius;float ratio = 1 - (rnorm - 1)*(rnorm - 1)*0.5;//映射原位置float UX = warpX + ratio * (i - warpX);float UY = warpY + ratio * (j - warpY);//根据双线性插值得到UX UY的值BilinearInsert(img, dst, UX, UY, i, j);}}}
}

这其中使用到了双线性插值算法,因此也去查看了双线性插值算法原理,这里我只是对每一个像素点单独进行双线性插值如下:

void BeautyCam::BilinearInsert(Mat &src, Mat &dst, float ux, float uy, int i, int j)
{auto Abs = [&](float f) {return f > 0 ? f : -f;};int c = src.channels();if (c == 3){//存储图像得浮点坐标CvPoint2D32f uv;CvPoint3D32f f1;CvPoint3D32f f2;//取整数int iu = (int)ux;int iv = (int)uy;uv.x = iu + 1;uv.y = iv + 1;//step图象像素行的实际宽度  三个通道进行计算(0 , 1 2  三通道)f1.x = ((uchar*)(src.data + src.step*iv))[iu * 3] * (1 - Abs(uv.x - iu)) + \((uchar*)(src.data + src.step*iv))[(iu + 1) * 3] * (uv.x - iu);f1.y = ((uchar*)(src.data + src.step*iv))[iu * 3 + 1] * (1 - Abs(uv.x - iu)) + \((uchar*)(src.data + src.step*iv))[(iu + 1) * 3 + 1] * (uv.x - iu);f1.z = ((uchar*)(src.data + src.step*iv))[iu * 3 + 2] * (1 - Abs(uv.x - iu)) + \((uchar*)(src.data + src.step*iv))[(iu + 1) * 3 + 2] * (uv.x - iu);f2.x = ((uchar*)(src.data + src.step*(iv + 1)))[iu * 3] * (1 - Abs(uv.x - iu)) + \((uchar*)(src.data + src.step*(iv + 1)))[(iu + 1) * 3] * (uv.x - iu);f2.y = ((uchar*)(src.data + src.step*(iv + 1)))[iu * 3 + 1] * (1 - Abs(uv.x - iu)) + \((uchar*)(src.data + src.step*(iv + 1)))[(iu + 1) * 3 + 1] * (uv.x - iu);f2.z = ((uchar*)(src.data + src.step*(iv + 1)))[iu * 3 + 2] * (1 - Abs(uv.x - iu)) + \((uchar*)(src.data + src.step*(iv + 1)))[(iu + 1) * 3 + 2] * (uv.x - iu);((uchar*)(dst.data + dst.step*j))[i * 3] = f1.x*(1 - Abs(uv.y - iv)) + f2.x*(Abs(uv.y - iv));  //三个通道进行赋值((uchar*)(dst.data + dst.step*j))[i * 3 + 1] = f1.y*(1 - Abs(uv.y - iv)) + f2.y*(Abs(uv.y - iv));((uchar*)(dst.data + dst.step*j))[i * 3 + 2] = f1.z*(1 - Abs(uv.y - iv)) + f2.z*(Abs(uv.y - iv));}
}

整体的一个大眼效果就完成了。

7.回调函数  瘦脸效果调节

void BeautyCam::on_thinFace(int b, void*userdata)
{Mat src = *((Mat *)userdata);Mat dst = src.clone();for (auto points_vec : m_pIntance->m_vecFaceData){Point2f endPt = points_vec[34];for (int i = 3; i < 15; i = i + 2){Point2f start_landmark = points_vec[i];Point2f end_landmark = points_vec[i + 2];//计算瘦脸距离(相邻两个点算距离)/*float dis = sqrt((start_landmark.x - end_landmark.x) * (start_landmark.x - end_landmark.x) +(start_landmark.y - end_landmark.y) * (start_landmark.y - end_landmark.y));*/float dis = b;dst = m_pIntance->LocalTranslationWarp_Face(dst, start_landmark.x, start_landmark.y, endPt.x, endPt.y, dis);}}imshow("BeautyCam", dst);
}

在这里就没有选择进行选定指定特征点进行计算距离,我直接使用滑条值来作为瘦脸距离进行操作的。具体可以根据上面68特征点采取几个点来计算瘦脸距离。

图像局部平移算法代码实现:

 Mat dst = img.clone();//平移距离 float ddradius = radius * radius;//计算|m-c|^2size_t mc = (endX - warpX)*(endX - warpX) + (endY - warpY)*(endY - warpY);//计算 图像的高  宽 通道数量int height = img.rows;int width = img.cols;int chan = img.channels();auto Abs = [&](float f) {return f > 0 ? f : -f;};for (int i = 0; i < width; i++){for (int j = 0; j < height; j++){// # 计算该点是否在形变圆的范围之内//# 优化,第一步,直接判断是会在(startX, startY)的矩阵框中if ((Abs(i - warpX) > radius) && (Abs(j - warpY) > radius))continue;float distance = (i - warpX)*(i - warpX) + (j - warpY)*(j - warpY);if (distance < ddradius){//# 计算出(i, j)坐标的原坐标//# 计算公式中右边平方号里的部分float ratio = (ddradius - distance) / (ddradius - distance + mc);ratio *= ratio;//映射原位置float UX = i - ratio * (endX - warpX);float UY = j - ratio * (endY - warpY);//根据双线性插值得到UX UY的值BilinearInsert(img, dst, UX, UY, i, j);//改变当前的值}}}return dst;}

以上两个平移和缩放算法主要就是根据python代码来进行封装的,整体效果还行,但还是需要不断的优化和更改。

8.回调函数 美颜磨皮算法

原理是使用opencv自带的人脸训练数据来获取人脸矩阵数据,进行双边滤波和高斯模糊来实现的;

美颜磨皮算法公式:

代码实现如下:

void BeautyCam::on_beautyFace(int b, void*userdata)
{Mat src = *((Mat *)userdata);Mat img = src.clone();double scale = 1.3;CascadeClassifier cascade = m_pIntance->loadCascadeClassifier("./haarcascade_frontalface_alt.xml");//人脸的训练数据CascadeClassifier netcascade = m_pIntance->loadCascadeClassifier("./haarcascade_eye_tree_eyeglasses.xml");//人眼的训练数据if (cascade.empty() || netcascade.empty())return;m_pIntance->detectAndDraw(img, cascade, scale,b);if (m_pIntance->isDetected == false){cout << "enter" << endl;Mat dst;int value1 = 3, value2 = 1;int dx = value1 * 5;    //双边滤波参数之一  //double fc = value1 * 12.5; //双边滤波参数之一  double fc = b;int p = 50;//透明度  Mat temp1, temp2, temp3, temp4;//对原图层image进行双边滤波,结果存入temp1图层中bilateralFilter(img, temp1, dx, fc, fc);//将temp1图层减去原图层image,将结果存入temp2图层中temp2 = (temp1 - img + 128);//高斯模糊  GaussianBlur(temp2, temp3, Size(2 * value2 - 1, 2 * value2 - 1), 0, 0);//以原图层image为基色,以temp3图层为混合色,将两个图层进行线性光混合得到图层temp4temp4 = img + 2 * temp3 - 255;//考虑不透明度,修正上一步的结果,得到最终图像dstdst = (img*(100 - p) + temp4 * p) / 100;dst.copyTo(img);}imshow("BeautyCam", img);
}

美颜效果主要是通过双边滤波参数来调节的。

void BeautyCam::detectAndDraw(Mat& img, CascadeClassifier& cascade,  double scale, int val)
{std::vector<Rect> faces;const static Scalar colors[] = { CV_RGB(0,0,255),CV_RGB(0,128,255),CV_RGB(0,255,255),CV_RGB(0,255,0),CV_RGB(255,128,0),CV_RGB(255,255,0),CV_RGB(255,0,0),CV_RGB(255,0,255) };//用不同的颜色表示不同的人脸//将图片缩小,加快检测速度Mat gray, smallImg(cvRound(img.rows / scale), cvRound(img.cols / scale), CV_8UC1);//因为用的是类haar特征,所以都是基于灰度图像的,这里要转换成灰度图像cvtColor(img, gray, CV_BGR2GRAY);resize(gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR);//将尺寸缩小到1/scale,用线性插值equalizeHist(smallImg, smallImg);//直方图均衡cascade.detectMultiScale(smallImg, //image表示的是要检测的输入图像faces,//objects表示检测到的人脸目标序列1.1, //caleFactor表示每次图像尺寸减小的比例2, //minNeighbors表示每一个目标至少要被检测到3次才算是真的目标(因为周围的像素和不同的窗口大小都可以检测到人脸),0 | CASCADE_SCALE_IMAGE ,//minSize为目标的最小尺寸Size(30, 30)); //minSize为目标的最大尺寸int i = 0;//遍历检测的矩形框for (std::vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++, i++){isDetected = true;Mat smallImgROI;std::vector<Rect> nestedObjects;Point center, left, right;Scalar color = colors[i % 8];int radius;center.x = cvRound((r->x + r->width*0.5)*scale);//还原成原来的大小center.y = cvRound((r->y + r->height*0.5)*scale);radius = cvRound((r->width + r->height)*0.25*scale);left.x = center.x - radius;left.y = cvRound(center.y - radius * 1.3);if (left.y < 0){left.y = 0;}right.x = center.x + radius;right.y = cvRound(center.y + radius * 1.3);if (right.y > img.rows){right.y = img.rows;}/*原理算法美肤-磨皮算法Dest =(Src * (100 - Opacity) + (Src + 2 * GuassBlur(EPFFilter(Src) - Src + 128) - 256) * Opacity) /100 ;*///绘画识别的人脸框//rectangle(img, left, right, Scalar(255, 0, 0));Mat roi = img(Range(left.y, right.y), Range(left.x, right.x));Mat dst;int value1 = 3, value2 = 1;int dx = value1 * 5;    //双边滤波参数之一  //double fc = value1 * 12.5; //双边滤波参数之一 double fc = val;//变化值int p = 50;//透明度  Mat temp1, temp2, temp3, temp4;//双边滤波    输入图像 输出图像 每像素领域的直径范围颜色空间过滤器的sigma  坐标空间滤波器的sigma bilateralFilter(roi, temp1, dx, fc, fc);temp2 = (temp1 - roi + 128);//高斯模糊  GaussianBlur(temp2, temp3, Size(2 * value2 - 1, 2 * value2 - 1), 0, 0);temp4 = roi + 2 * temp3 - 255;dst = (roi*(100 - p) + temp4 * p) / 100;dst.copyTo(roi);}
}

到此,美白磨皮的简单功能就实现了。

参考:https://blog.csdn.net/zhangqipu000/article/details/53260647 opencv 美白磨皮人脸检测

整体效果只是简单的实现,如果要运用到项目中,问题还是很多的,需要不断的优化和算法的更改呀。作为最近学习opencv的一个简单demo,来巩固知识点。

C++ / Opencv 简单实现美颜效果(瘦脸、大眼、磨皮等)相关推荐

  1. 模糊处理(下)--高斯模糊,双边模糊以及实现一个简单的磨皮美颜效果(opencv学习记录--4)

    文章目录 1.高斯模糊 1.什么是高斯模糊 2.opencv提供的API 2.双边模糊 1.什么是双边模糊 2.opencv的API 3.磨皮美颜效果的实现 1.实现过程 2.主要代码 3.效果 参考 ...

  2. OpenCV 利用高斯模糊实现简单的磨皮美颜效果

    1.高斯模糊 首先高斯指的是高斯函数,这个我想大家应该都知道,是一种非常常见的概率分布函数.大概就长这样吧. 通过均值模糊类比,我们可以大胆的猜出来高斯模糊的含义: 每一次需要处理的像素矩阵中不同地方 ...

  3. opencv 简单美颜效果

    美颜效果采用:双边模糊(也称双边滤波)+掩膜操作 双边模糊bilateralFilter(src, dest, d=15, 150, 3) 15 –计算的半径,半径之内的像数都会被纳入计算,如果提供- ...

  4. android 瘦脸模式 sdk,大眼瘦脸加磨皮通通不能少,论美颜SDK是如何实现的

    原标题:大眼瘦脸加磨皮通通不能少,论美颜SDK是如何实现的 现在还有人不喜欢强大的美颜吗?要说之前技术不成熟的时候,美颜效果容易失真,瘦脸容易成锥子脸,那么这几年来所实现的美颜可以强大到什么地步呢?就 ...

  5. OpenGL ES 实现瘦脸大眼效果

    该原创文章首发于微信公众号:字节流动 旧文中我们用 OpenGL 给小姐姐实现了瘦身和大长腿效果,结果小姐姐眯着眼睛.嘟着嘴说,我需要瘦身和大长腿效果吗? 笔者若有所思地看着她的眼睛和脸庞,终于弄明白 ...

  6. matlab瘦脸大眼的代码,OpenGL ES 实现瘦脸大眼效果

    Hi 小姐姐,这是你要的大眼瘦脸效果? 该原创文章首发于微信公众号:字节流动 旧文中我们用 OpenGL 给小姐姐实现了瘦身和大长腿效果,结果小姐姐眯着眼睛.嘟着嘴说,我需要瘦身和大长腿效果吗? 笔者 ...

  7. 网红直播时的瘦脸、磨皮等美颜功能是如何实现的?

    作者 | 阿里文娱算法专家彰三 出品 | AI科技大本营(ID:rgznai100) 背景 随着移动设备的发展,美颜已成为多媒体内容生成链路中不可缺少的一种基本能力,尤其是在来疯直播秀场业务的场景下, ...

  8. 在OpenGL中利用shader进行实时瘦脸大眼等脸型微调

    在OpenGL中利用shader进行实时瘦脸大眼等脸型微调 在现在这个靠脸吃饭的时代,如果你没有一张瓜子脸一双大眼睛,那还怎么去吃饭呢,而现在一些直播视频App相机应用基本都会有瘦脸大眼效果.本文是在 ...

  9. iOS原生框架Vision实现瘦脸大眼特效

    一.背景说明 一般短视频项目中会使用类似Face++这样的商业sdk实现瘦脸大眼特效,想到苹果的原生框架Vision也可以进行人脸识别,提取人脸特征点,应该也能实现.没想到挺顺利,参考了网上的相关算法 ...

最新文章

  1. 撬开骁龙8一看,满满都是顶会论文
  2. 随机信号通过带通滤波器
  3. Eclipse搭建Cocos2d-x运行环境问题汇总(不含CygWin)
  4. python 遍历数组gbk编码_python bytes和bytearray、编码和解码
  5. glassfish 自定义 jaas realm
  6. centos免密登录
  7. MarkDown编辑器中数学公式与符号-LaTeX 各种数学命令,符号
  8. redies集群方案
  9. 云计算机资源池,IaaS云资源池-云计算.PDF
  10. 【React】【Ant Deign】手机验证码登录效果实现
  11. 微信分享图片URL不显示问题
  12. MOOC中国大学慕课C语言期末编程试题
  13. Vue.js删除子组件数据显示异常,重新销毁创建子组件
  14. 人人商城图片错乱问题
  15. 惠普彩色激光打印机CM1312送稿台卡纸不能消除解决办法
  16. Mysql delete删除表数据之后,表空间没有释放的问题
  17. 计算机所有以太网适配的ip,演示win10电脑以太网没有有效的ip配置
  18. list.stream distinct列表去重
  19. px、em、rem单位间的区别
  20. python数字转大写字母_python变量名称如何转化为大写字母?

热门文章

  1. eval和assert
  2. 网件R7800刷OpenWrt固件单臂路由设置经历
  3. 未来科学大奖迎首位女性得主:密码学家王小云获百万美元奖金
  4. 10.7. Transformer
  5. 照明基础知识(一)---白炽灯(热辐射光源)发展史工作原理
  6. switch动森amiibo数据_《Switch动物之森》amiibo攻略 amiibo卡有什么用
  7. cdi name 日志_DI / CDI –基础
  8. FLT3_ITD分析
  9. 美拍sig算法so分析
  10. 利用金山快盘和TortoiseSVN搭建自己的svn服务器