demo地址:http://download.csdn.net/download/jueyi1127/10175882

在图形图像处理教程的第一节,主要讲解位图图像原图的修改。一但你明白基本的图形处理方法,那么其它的相关内容你也会较容易的弄明白。在教程的第二部分,主要介绍另外的三种修改图像

(via: 泰然网)
想象一张最好的生活自拍照。它是很高大尚滴并且以后会有用武之地。转发,票选将会使你获得成千上万份的关注,因为它确实很酷很帅。现在,如果你有什么办法,可以让它看起来更加的高大尚。。。
这就是图形图像处理要做到的!它可以让你的照片带上更多的特殊效果,比如修改颜色,与其它的图片进行合成等等。
在这两部分教程中,你需要先弄明白一些图形图像处理的基础知识。接着,你可以利用如下四个流行的图形图像处理方法编写一个实现“幽灵图像过滤器”的程序:
1:位图图像原图修改
2:使用Core Graphics库
3:使用Core Image库
4:使用GPUImage库的第三部分
在图形图像处理教程的第一节,主要讲解位图图像原图的修改。一但你明白基本的图形处理方法,那么其它的相关内容你也会较容易的弄明白。在教程的第二部分,主要介绍另外的三种修改图像方法。
本教程假设你拥有关于IOS系统和Object-C的基础,但在开始本教程前不需要拥有任何关于图形图像处理的知识。
开始
在开始写代码之前,先理解一些关于图形图像处理的基本概念很是需要。所以,先别急,放轻松,让我们在最短的时间里去了解一下图形图像的内部工作原理。
第一件事情,看一下我们本教程中的新朋友...幽灵!
不要怕,幽灵不是真的鬼魂。实际上,它只是一张图像。简单来说,它就是由一堆1和0组成的。这样说听上去会更好一些。
什么是图形图像
一张图像就是像素点的集合,每一个像素都是一个单独,明了的颜色。图像一般情况下都存储成数组,你可以把他们相像成2维数组。
这一张是缩放版本的幽灵,被放大后:
图像中这些小的“方块”就是像素,每一像素只表示一种颜色。当成百上千万的像素集体到一起后,就构成了图形图像。
如何用字节来表示颜色
表示图形的方式有许多种。在本教程中使用的是最简单的:32位RGBA模式。
如同它的名字一样,32位RGBA模式会将一个颜色值存储在32位,或者4个字节中。每一个字节存储一个部分或者一个颜色通道。这4个部分分别是:
~ R代表红色
~ G代表绿色
~ B代表蓝色
~ A代表透明度
正如你所知道的,红,绿和蓝是所有颜色的基本颜色集。你几乎可以使用他们创建搭配出任何想要的颜色。
由于使用8位表示每一种颜色值,那么使用32位RGBA模式实际上可以创建出不透明的颜色的总数是256256256种,已经接近17亿种。惊叹,那是好多好多好多的颜色!
alpha通道与其它的不同。你可以把它当成透明的东西,就像UIView的alpah属性。
透明颜色意味着没有任何的颜色,除非在它的后面有另外一种颜色;它的主要功能就是要告诉图像处理这个像素的透明度是多少,于是,就会有多少颜色值穿透过它而显示出来。
你将会通过本节后面的内容更新深入的了解。
总结一下,一个图形就是像素的集体,并且每一个像素只能表示一种颜色。本节,你已经了解了32位RGBA模式。
提示:你有没有想过,位图的结构组成?一张位图就是一张2D的地图,每一块就是一个像素!像素就是地图的每一块。哈哈!
现在你已经了解了用字节表示颜色的基础了。不过在你开始着手写代码前,还有三个以上的概念需要你了解。
颜色空间
使用RGB模式表示颜色是颜色空间的一个例子。它只是众多存储颜色方法中的一种。另外一种颜色空间是灰阶空间。像它的名字一样,所有的图形都只有黑和白,只需要保存一个值来表示这种颜色。
下面这种使用RGB模式表示的颜色,人类的肉眼是很难识别的。
Red: 0 Green:104 Blue:55
你认为RGB值为[0,104,55]会产生一种什么颜色?
认真的思考一下,你也许会说是一种蓝绿色或者绿色,但那是错的。原来,你所看到的是深绿色。
另外两种比较常见的颜色空间是HSV和YUV。
HSV,使用色调,饱和度和亮度来直观的存储颜色值。你可以把这三个部分这样来看:
·色调就是颜色
·饱和度就是这个颜色有多么的饱满
·值就是颜色的亮度有多亮
在这种颜色空间中,如果你发现自己并不知道HSV的值,那么通过它的三个值,可以很容易的相像出大概是什么颜色。
RGB和HSV颜色空间的区别是很容易理解的,请看下面的图像:
YUV是另外一种常见的颜色空间,电视机使用的就是这种方式。
最开始的时候,电视机只有灰阶空间一种颜色通道。后来,当彩色电影出现后,就有了2种通道。当然,如果你想在本教程中使用YUV,那么你需要去研究更多关于YUV和其它颜色空间的相关知识。
NOTE:同样的颜色空间,你也可以使用不同的方法表示颜色。比如16位RGB模式,可以使用5个字节存储R,6个字节存储G,5个字节存储B。
为什么用6个字节存储绿色,5个字节存储蓝色?这是一个有意思的问题,答案就是因为眼球。人类的眼球对绿色比较敏感,所以人类的眼球更空间分辨出绿色的颜色值变化。
坐标系统
既然一个图形是由像素构成的平面地图,那么图像的原点需要说明一下。通常原点在图像的左上角,Y轴向下;或者原点在图像的左下,Y轴向上。
没有固定的坐标系统,苹果在不同的地方可能会使用不同的坐标系。
目前,UIImage和UIView使用的是左上原点坐标,Core Image和Core Graphics使用的是左下原点坐标。这个概念很重要,当你遇到图像绘制倒立问题的时候你就知道了。
图形压缩
这是在你开始编写代码前的最后一个需要了解的概念了!原图的每一个像素都被存储在各自的内存中。
如果你使用一张8像素的图形做运算,它将会消耗810^6像素4比特/像素=32兆字节内存。关注一下数据!
这就是为什么会出现jpeg,png和其它图形格式的原因。这些都是图形压缩格式。
当GPU在绘制图像的时候,会使用大量内存把图像的原始尺寸进行解压缩。如果你的程序占用了过多的内存,那么操作系统会将进程杀死(程序崩溃)。所以请确定你的程序使用较大的图像进行过测试。
我需要一些行动…
关注一下像素
现在,你已经基础了解了图形图像的内部工作原理,已经可以开始编写代码喽。今天你将会开发一款改变自己照片的程序,叫做SpookCam,该程序会把一张幽灵的图像放到你的照片中!
下载工具包在xcode中打开该项目,编译并运行。在你的手机上会看到如下的图像:
在控制台,你会看到如下的输出:
当前的程序可以加载这张幽灵的图像,并得到图像的所有像素值,打印出每个像素的亮度值到日志中。
亮度值是神马?它就是红色,绿色和蓝色通过的平均值。
注意输出日志外围的亮度值都为0,这意味着他们代码的是黑色。然而,他们的透明度的值是0,所以它们是透明不可见的。为了证明这一点,试着将imageView的背景颜色设置成红色,然后再次编译并运行。
现在快速的浏览一下代码。ViewController.m 中使用 UIImagePickerController 来在相册中取得图像或者使用机机获得图像。
当它选定一张图像后,调用-setupWithImage:在这行中,输出了每一像素的亮度值到日志中。定位到ViewController.m中的logPixelsOfImage,查看方法中的开始部分:
     
  1. // 1.
  2. CGImageRef inputCGImage = [image CGImage];
  3. NSUInteger width =                 CGImageGetWidth(inputCGImage);
  4. NSUInteger height = CGImageGetHeight(inputCGImage);
  5. // 2.
  6. NSUInteger bytesPerPixel = 4;
  7. NSUInteger bytesPerRow = bytesPerPixel *     width;
  8. NSUInteger bitsPerComponent = 8;
  9. UInt32 * pixels;
  10. pixels = (UInt32 *) calloc(height * width,     sizeof(UInt32));
  11. // 3.
  12. CGColorSpaceRef colorSpace =     CGColorSpaceCreateDeviceRGB();
  13. CGContextRef context =     CGBitmapContextCreate(pixels, width, height,     bitsPerComponent, bytesPerRow, colorSpace,     kCGImageAlphaPremultipliedLast |     kCGBitmapByteOrder32Big);
  14. // 4.
  15. CGContextDrawImage(context, CGRectMake(0,     0, width, height), inputCGImage);
  16. // 5. Cleanup
  17. CGColorSpaceRelease(colorSpace);
  18. CGContextRelease(context);
现在,让我们分段的来看一下:
1:第一部分:把UIImage对象转换为需要被核心图形库调用的CGImage对象。同时,得到图形的宽度和高度。
2:第二部分:由于你使用的是32位RGB颜色空间模式,你需要定义一些参数bytesPerPixel(每像素大小)和bitsPerComponent(每个颜色通道大小),然后计算图像bytesPerRow(每行有大)。最后,使用一个数组来存储像素的值。
3:第三部分:创建一个RGB模式的颜色空间CGColorSpace和一个容器CGBitmapContext,将像素指针参数传递到容器中缓存进行存储。在后面的章节中将会进一步研究核图形库。
4:第四部分:把缓存中的图形绘制到显示器上。像素的填充格式是由你在创建context的时候进行指定的。
5:第五部分:清除colorSpace和context.
NOTE:当你绘制图像的时候,设备的GPU会进行解码并将它显示在屏幕。为了访问本地数据,你需要一份像素的复制,就像刚才做的那样。
此时此刻,pixels存储着图像的所有像素信息。下面的几行代码会对pixels进行遍历,并打印:
     
  1. // 1.
  2. #define Mask8(x) ( (x) & 0xFF )
  3. #define R(x) ( Mask8(x) )
  4. #define G(x) ( Mask8(x >> 8 ) )
  5. #define B(x) ( Mask8(x >> 16) )
  6. NSLog(@"Brightness of image:");
  7. // 2.
  8. UInt32 * currentPixel = pixels;
  9. for (NSUInteger j = 0; j < height; j++) {
  10. for (NSUInteger i = 0; i < width; i++) {
  11. // 3.
  12. UInt32 color = *currentPixel;
  13. printf("%3.0f ",     (R(color)+G(color)+B(color))/3.0);
  14. // 4.
  15. currentPixel++;
  16. }
  17. printf("\n");
  18. }
代码解释:
1:定义了一些简单处理32位像素的宏。为了得到红色通道的值,你需要得到前8位。为了得到其它的颜色通道值,你需要进行位移并取截取。
2:定义一个指向第一个像素的指针,并使用2个for循环来遍历像素。其实也可以使用一个for循环从0遍历到width*height,但是这样写更容易理解图形是二维的。
3:得到当前像素的值赋值给currentPixel并把它的亮度值打印出来。
4:增加currentPixel的值,使它指向下一个像素。如果你对指针的运算比较生疏,记住这个:currentPixel是一个指向UInt32的变量,当你把它加1后,它就会向前移动4字节(32位),然后指向了下一个像素的值。
提示:还有一种非正统的方法就是把currentPiexl声明为一个指向8字节的类型的指针,比如char。这种方法,你每增加1,你将会移动图形的下一个颜色通道。与它进行位移运算,你会得到颜色通道的8位数值。
此时此刻,这个程序只是打印出了原图的像素信息,但并没有进行任何修改!下面将会教你如何进行修改。
SpookCame-原图修改
四种研究方法都会在本小节进行,你将会花费更多的时间在本节,因为它包括了图形图像处理的第一原则。掌握了这个方法你会明白其它库所做的。
在本方法中,你会遍历每一个像素,就像之前做的那个,但这次,将会对每个像素进行新的赋值。
这种方法的优点是容易实现和理解;缺点就是扫描大的图形和效果的时候会更复杂,不精简。
正如你在程序开始看到的,ImageProcessor类已经存在。将它应用到ViewController中,替换-setupWithImage,代码如下:
     
  1. - (void)setupWithImage:(UIImage*)image {
  2. UIImage * fixedImage = [image     imageWithFixedOrientation];
  3. self.workingImage = fixedImage;
  4. // Commence with processing!
  5. [ImageProcessor     sharedProcessor].delegate = self;
  6. [[ImageProcessor sharedProcessor]     processImage:fixedImage];
  7. }
注释掉 -viewDidLoad 中下面的代码:
     
  1. // [self setupWithImage:[UIImage     imageNamed:@"ghost_tiny.png"]];
现在,打开 ImageProcessor.m。如你所见,ImageProcessor 是单例模式,调用 -processUsingPixels 来加载图像,然后通过 ImageProcessorDelegate 返回输出。
-processsUsingPixels:是之前你所看到获得图形像素代码的一种复制品,如同inputImage。注意两个额外的宏A(x)和RGBAMake(r,g,b,a)的定义,用来方便处理。
编译,并运行。从相册(拍照)选择一张图片,它将会出现在屏幕上:
照片中的人看上去在放松,是时候把幽灵放进去了!
在processUsingPixels的返回语句前,添加如下代码,创建一个幽灵的CGImageRef对象。
UIImage * ghostImage = [UIImage imageNamed:@"ghost"];
CGImageRef ghostCGImage = [ghostImage CGImage];
现在,做一些数学运算来确定幽灵图像放在原图的什么位置。
     
  1. CGFloat ghostImageAspectRatio =     ghostImage.size.width /     ghostImage.size.height;
  2. NSInteger targetGhostWidth = inputWidth *     0.25;
  3. CGSize ghostSize =     CGSizeMake(targetGhostWidth, targetGhostWidth     / ghostImageAspectRatio);
  4. CGPoint ghostOrigin =     CGPointMake(inputWidth * 0.5, inputHeight *     0.2);
以上代码会把幽灵的图像宽度缩小25%,并把它的原点设定在点ghostOrigin。
下一步是创建一张幽灵图像的缓存图,
     
  1. NSUInteger ghostBytesPerRow = bytesPerPixel * ghostSize.width;
  2. UInt32 * ghostPixels = (UInt32     *)calloc(ghostSize.width * ghostSize.height,     sizeof(UInt32));
  3. CGContextRef ghostContext =     CGBitmapContextCreate(ghostPixels,     ghostSize.width, ghostSize.height,
  4. bit    sPerComponent, ghostBytesPerRow, colorSpace,
  5. kCG    ImageAlphaPremultipliedLast |     kCGBitmapByteOrder32Big);
  6. CGContextDrawImage(ghostContext,     CGRectMake(0, 0, ghostSize.width,     ghostSize.height),ghostCGImage);
上面的代码和你从inputImage中获得像素信息一样。不同的地方是,图像会被缩小尺寸,变得更小了。
现在已经到了把幽灵图像合并到你的照片中的最佳时间了。
合并:像前面提到的,每一个颜色都有一个透明通道来标识透明度。并且,你每创建一张图像,每一个像素都会有一个颜色值。
所以,如果遇到有透明度和半透明的颜色值该如何处理呢?
答案是,对透明度进行混合。在最顶层的颜色会使用一个公式与它后面的颜色进行混合。公式如下:
     
  1. NewColor = TopColor * TopColor.Alpha + BottomColor * (1 - TopColor.Alpha)
这是一个标准的线性差值方程。
·当顶层透明度为1时,新的颜色值等于顶层颜色值。
·当顶层透明度为0时,新的颜色值于底层颜色值。
·最后,当顶层的透明度值是0到1之前的时候,新的颜色值会混合借于顶层和底层颜色值之间。
还可以用 premultiplied alpha的方法。
当处理成千上万像素的时候,他的性能会得以发挥。
好,回到幽灵图。
如同其它位图运算一样,你需要一些循环来遍历每一个像素。但是,你只需要遍历那些你需要修改的像素。
把下面的代码添加到processUsingPixels的下面,还是放在返回语句的前面:
     
  1. NSUInteger offsetPixelCountForInput = ghostOrigin.y * inputWidth + ghostOrigin.x;
  2. for (NSUInteger j = 0; j < ghostSize.height; j++) {
  3. for (NSUInteger i = 0; i < ghostSize.width; i++) {
  4. UInt32 * inputPixel = inputPixels + j * inputWidth + i + offsetPixelCountForInput;
  5. UInt32 inputColor = *inputPixel;
  6. UInt32 * ghostPixel = ghostPixels + j     * (int)ghostSize.width + i;
  7. UInt32 ghostColor = *ghostPixel;
  8. // Do some processing here
  9. }
  10. }
通过对幽灵图像像素数的循环和offsetPixelCountForInput获得输入的图像。记住,虽然你使用的是2维数据存储图像,但在内存他它实际上是一维的。
下一步,添加下面的代码到注释语句 Do some processing here的下面来进行混合:
     
  1. // Blend the ghost with 50% alpha
  2. CGFloat ghostAlpha = 0.5f * (A(ghostColor)     / 255.0);
  3. UInt32 newR = R(inputColor) * (1 -     ghostAlpha) + R(ghostColor) * ghostAlpha;
  4. UInt32 newG = G(inputColor) * (1 -     ghostAlpha) + G(ghostColor) * ghostAlpha;
  5. UInt32 newB = B(inputColor) * (1 -     ghostAlpha) + B(ghostColor) * ghostAlpha;
  6. // Clamp, not really useful here :p
  7. newR = MAX(0,MIN(255, newR));
  8. newG = MAX(0,MIN(255, newG));
  9. newB = MAX(0,MIN(255, newB));
  10. *inputPixel = RGBAMake(newR, newG, newB,     A(inputColor));
这部分有2点需要说明:
1:你将幽灵图像的每一个像素的透明通道都乘以了0.5,使它成为半透明状态。然后将它混合到图像中像之前讨论的那样。
2:clamping部分将每个颜色的值范围进行限定到0到255之间,虽然一般情况下值不会越界。但是,大多数情况下需要进行这种限定防止发生意外的错误输出。
最后一步,添加下面的代码到 processUsingPixels 的下面,替换之前的返回语句:
     
  1. // Create a new UIImage
  2. CGImageRef newCGImage =     CGBitmapContextCreateImage(context);
  3. UIImage * processedImage = [UIImage     imageWithCGImage:newCGImage];
  4. return processedImage;
上面的代码创建了一张新的UIImage并返回它。暂时忽视掉内存泄露问题。编译并运行,你将会看到漂浮的幽灵图像:
好了,完成了,这个程序简直就像个病毒!
黑白颜色
最后一种效果。尝试自己实现黑白颜色效果。为了做到这点,你需要把每一个像素的红色,绿色,蓝色通道的值设定成三个通道原始颜色值的平均值,就像开始的时候输出幽灵图像所有像素亮度值那样。
在注释语句// create a new UIImage前添加上一步的代码 。
找到了吗?
     
  1. // Convert the image to black and white
  2. for (NSUInteger j = 0; j < inputHeight; j++) {
  3. for (NSUInteger i = 0; i < inputWidth; i++) {
  4. UInt32 * currentPixel = inputPixels + (j * inputWidth) + i;
  5. UInt32 color = *currentPixel;
  6. // Average of RGB = greyscale
  7. UInt32 averageColor = (R(color) +     G(color) + B(color)) / 3.0;
  8. *currentPixel = RGBAMake(averageColor,     averageColor, averageColor, A(color));
  9. }
  10. }
最后的一步就是清除内存。ARC不能代替你对CGImageRefs和CGContexts进行管理。添加如下代码到返回语句之前。
     
  1. CGColorSpaceRelease(colorSpace);
  2. CGContextRelease(context);
  3. CGContextRelease(ghostContext);
  4. free(inputPixels);
  5. free(ghostPixels);
编译并运行,不要被结果吓到:
下面需要做的:
恭喜!你已经完成了自己的第一个图像处理程序。你可以在这里下载该工程的源代码。
还不错吧?你可以尝试修改一下循环中的代码创建自己想要的效果,尝试下实现下面的效果:
·尝试调换图像的红色和蓝色通道值
·提高图像的亮度10%
·作为进一步的挑战,尝试只使用基于像素的方法缩放幽灵的图像,下面是步骤:
1:使用幽灵图像的尺寸大小创建一个新的CGContext。
2:在原图像中得到你想要的并赋值到新的缓存图像中。
3:附加,尝试在像素之前进行计算并插入相似值像素点。如果你可以在四个像素间进行插入,你自己就已经实现 Bilinear scaling(双线性插值法)了!太牛了!
如果你已经完成了第一个项目,想必你对图形图像的处理已经有了基本的概念。现在你可以尝试使用更快更好的方法来实现相同的效果。
在下一章节中,你将会使用另外三个新的方法替换-processUsingPixels:完成相同的任务。一定要看丫!
同时,如果你对该章节有任何疑问和不解,请留言给我!
转载自:http://www.cocoachina.com/industry/20140812/9363.html

iOS中图形图像处理第一部分:位图图像原图修改相关推荐

  1. iOS中的图像处理(一)——基础滤镜

    最近在稍微做一些整理,翻起这部分的代码,发现是两个多月前的了. 这里讨论的是基于RGBA模型下的图像处理,即将变换作用在每个像素上. 代码是以UIImage的category形式存在的: [cpp] ...

  2. 【图形图像处理】之位图图像和矢量图形有何区别?

    位图特点:会因为图形放大而变得图形不可辨认.矢量图特点:图形放大缩小不会改变图形辨认度. 一.主体不同 1.位图图像:由称作像素(图片元素)的单个点组成的. 2.矢量图形:根据几何特性来绘制图形,矢量 ...

  3. OpenCV-Python图形图像处理:利用TopHat顶帽获取背景色中的噪点

    ☞ ░ 前往老猿Python博客 https://blog.csdn.net/LaoYuanPython ░ 一.顶帽简介 顶帽(Top Hat),又称"礼帽"运算,其结果图像为原 ...

  4. 计算机技术在图形图像处理中的应用,计算机技术在图形图像处理中的应用研究...

    计算机技术在图形图像处理中的应用研究 摘要随着人们生存生活的发展和进步,计算机图形和图像的处理技术就会越来越好,越来越形象和逼真了.计算机图形和图像的处理技术在很多的领域里发挥着非常重要的作用.本文主 ...

  5. 国内外计算机专业图形图像处理课程现状,中职学校Photoshop图形图像处理课程的教学反思...

    施树英 [摘 要]本文分析中职学校 Photoshop 课程的教学现状,并结合教学实际情况,从课程本身.学生.教师的教学方法三个层面对 Photoshop 图形图像处理课程教学进行反思,提出联系生活激 ...

  6. 中职计算机图形图像课程标准,计算机图形与图形图像处理技术的相互结合

    钟志锋 [摘 要] 随着社会的不断发展和进步,中职教育也越发需要进步和更新才可以适应新时期对中职学生的要求.而计算机图形与图形图像处理技术也是顺应时代而生的新兴技术.计算机图形与图形图像处理技术已经成 ...

  7. 计算机技术在美术方面的应用,计算机技术在图形图像处理中的应用

    周明伟 王艳 摘要:计算机技术作为当下流行的技术之一,受到了越来越多的关注,无论是人们的日程生活,还是各行各业的发展生产过程当中都离不开计算机技术.在科学技术高度发达的今天,计算机技术得到了不断地创新 ...

  8. 计算机在多媒体技术中的应用研究,计算机技术在图形图像处理中的应用研究

    计算机技术在图形图像处理中的应用研究 随着信息技术的发展,图像处理技术在日常生活中的应用越来越普遍,下面是小编搜集整理的一篇探究计算机技术在图形图像处理应用的论文范文,供大家阅读参考. 摘要:随着计算 ...

  9. 手机直播系统开发中关于iOS获取图形验证码功能

    在手机直播系统开发中关于iOS获取图形验证码功能介绍,首先进入注册页面后请求图形验证码接口获取图形验证码的数字组合,然后加载到相应的页面上,在图形验证码页面我们定义了几个属性,字符串的数量.显示的线条 ...

最新文章

  1. NOIP2010-普及组复赛模拟试题-第一题-手机
  2. ERROR Streaming result set com.mysql.jdbc.RowDataDynamic@1d5a7f6 is still active. No statements may
  3. 50 CO配置-控制-获利能力分析-维护经营关注点
  4. 唏嘘!一代手机OS退场:没生态、没开发者是失败主因
  5. 图解算法之排序算法(5)——归并排序
  6. 工作中最重要的个人品质--独立
  7. python中json怎么转换成字典
  8. 太阳方位角 太阳天顶角
  9. 如何在Ubuntu 16.04上使用ProxySQL缓存优化MySQL查询
  10. attempted to return null from a method with a primitive return type (int).
  11. 最新文本转语音的接口(免费),百度语音作废
  12. python在冒号处显示语法错误_python冒号错误语法无效
  13. ENVI|一天一个小技能|APP STORE浏览并下载矢量数据
  14. 基于Xilinx Kintex-7 FPGA K7 XC7K325T PCIeX8 四路光纤卡226
  15. 神经网络和深度神经网络,图神经网络和神经网络
  16. Linux版csgo调全屏窗口,csgo全屏和全屏窗口 哔哩哔哩直播姬黑屏解决方法
  17. Debian9的各个版本的下载地址
  18. Prime Day首日遇宕机和罢工,AWS遭网友群嘲太low?
  19. 用友计算机审计实验步骤,计算机审计上机实验报告模板详解.doc
  20. 2011:那些逝去的IT英才

热门文章

  1. Web基础之与Tomcat的初次相遇
  2. 保证一天不困的25个小方法
  3. 基于声网SDK的双师授课系统开发
  4. JavaScript设计模式-享元模式
  5. linux解决挖矿病毒
  6. IO流输入输出流入门详解
  7. 程序猿同城对调要学会对自己的工作进行总结
  8. C1驾照考试流程详解
  9. LeetCode有效的括号
  10. 22部电影折射出22句爱情箴言