图像处理------泛洪填充算法(Flood Fill Algorithm) 油漆桶功能-阿里云开发者社区

开发者社区> 毛毛虫的爹> 正文

图像处理------泛洪填充算法(Flood Fill Algorithm) 油漆桶功能

简介: <p style="color: rgb(51, 51, 51); font-family: Arial; font-size: 14px; line-height: 26px;">泛洪填充算法(Flood Fill Algorithm)</p> <p style="color: rgb(51, 51, 51); font-family: Arial; font-size: 14px; lin
+关注继续查看

泛洪填充算法(Flood Fill Algorithm)

泛洪填充算法又称洪水填充算法是在很多图形绘制软件中常用的填充算法,最熟悉不过就是

windows paint的油漆桶功能。算法的原理很简单,就是从一个点开始附近像素点,填充成新

的颜色,直到封闭区域内的所有像素点都被填充新颜色为止。泛红填充实现最常见有四邻域

像素填充法,八邻域像素填充法,基于扫描线的像素填充方法。根据实现又可以分为递归与

非递归(基于栈)。

 

在介绍算法的三种实现方式之前,首先来看一下测试该算法的UI实现。基本思路是选择一

张要填充的图片,鼠标点击待填充的区域内部,算法会自动填充该区域,然后UI刷新。完

整的UI代码如下:

[java] view plaincopy
  1. package com.gloomyfish.paint.fill;  
  2.   
  3. import java.awt.Color;  
  4. import java.awt.Dimension;  
  5. import java.awt.Graphics;  
  6. import java.awt.Graphics2D;  
  7. import java.awt.MediaTracker;  
  8. import java.awt.event.MouseEvent;  
  9. import java.awt.event.MouseListener;  
  10. import java.awt.image.BufferedImage;  
  11. import java.io.File;  
  12. import java.io.IOException;  
  13.   
  14. import javax.imageio.ImageIO;  
  15. import javax.swing.JComponent;  
  16. import javax.swing.JFileChooser;  
  17. import javax.swing.JFrame;  
  18.   
  19. public class FloodFillUI extends JComponent implements MouseListener{  
  20.       
  21.     /** 
  22.      *  
  23.      */  
  24.     private static final long serialVersionUID = 1L;  
  25.     private BufferedImage rawImg;  
  26.     private MediaTracker tracker;  
  27.     private Dimension mySize;  
  28.     FloodFillAlgorithm ffa;  
  29.     public FloodFillUI(File f)  
  30.     {  
  31.         try {  
  32.             rawImg = ImageIO.read(f);  
  33.         } catch (IOException e1) {  
  34.             e1.printStackTrace();  
  35.         }  
  36.           
  37.         tracker = new MediaTracker(this);  
  38.         tracker.addImage(rawImg, 1);  
  39.           
  40.         // blocked 10 seconds to load the image data  
  41.         try {  
  42.             if (!tracker.waitForID(110000)) {  
  43.                 System.out.println("Load error.");  
  44.                 System.exit(1);  
  45.             }// end if  
  46.         } catch (InterruptedException e) {  
  47.             e.printStackTrace();  
  48.             System.exit(1);  
  49.         }// end catch  
  50.           
  51.         mySize = new Dimension(300300);  
  52.         this.addMouseListener(this);  
  53.         ffa = new FloodFillAlgorithm(rawImg);  
  54.         JFrame imageFrame = new JFrame("Flood File Algorithm Demo - Gloomyfish");  
  55.         imageFrame.getContentPane().add(this);  
  56.         imageFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
  57.         imageFrame.pack();  
  58.         imageFrame.setVisible(true);  
  59.     }  
  60.   
  61.     public void paint(Graphics g) {  
  62.         Graphics2D g2 = (Graphics2D) g;  
  63.         g2.drawImage(rawImg, 1010, rawImg.getWidth(), rawImg.getHeight(), null);  
  64.     }  
  65.     public Dimension getPreferredSize() {  
  66.         return mySize;  
  67.     }  
  68.       
  69.     public Dimension getMinimumSize() {  
  70.         return mySize;  
  71.     }  
  72.       
  73.     public Dimension getMaximumSize() {  
  74.         return mySize;  
  75.     }  
  76.       
  77.     public static void main(String[] args) {  
  78.         JFileChooser chooser = new JFileChooser();  
  79.         chooser.showOpenDialog(null);  
  80.         File f = chooser.getSelectedFile();  
  81.         new FloodFillUI(f);  
  82.     }  
  83.   
  84.     @Override  
  85.     public void mouseClicked(MouseEvent e) {  
  86.         System.out.println("Mouse Clicked Event!!");  
  87.         int x = (int)e.getPoint().getX();  
  88.         int y = (int)e.getPoint().getY();  
  89.         System.out.println("mouse location x = " + x); // column  
  90.         System.out.println("mouse location y = " + y); // row  
  91.         System.out.println();  
  92.         long startTime = System.nanoTime();  
  93.         // ffa.floodFill4(x, y, Color.GREEN.getRGB(), ffa.getColor(x, y));  
  94.         // ffa.floodFill8(x, y, Color.GREEN.getRGB(), ffa.getColor(x, y));  
  95.         // ffa.floodFillScanLine(x, y, Color.GREEN.getRGB(), ffa.getColor(x, y)); // 13439051  
  96.         ffa.floodFillScanLineWithStack(x, y, Color.GREEN.getRGB(), ffa.getColor(x, y)); // - 16660142  
  97.         long endTime = System.nanoTime() - startTime;  
  98.         System.out.println("run time = " + endTime);  
  99.         ffa.updateResult();  
  100.         this.repaint();  
  101.     }  
  102.   
  103.     @Override  
  104.     public void mousePressed(MouseEvent e) {  
  105.         // TODO Auto-generated method stub  
  106.           
  107.     }  
  108.   
  109.     @Override  
  110.     public void mouseReleased(MouseEvent e) {  
  111.         // TODO Auto-generated method stub  
  112.           
  113.     }  
  114.   
  115.     @Override  
  116.     public void mouseEntered(MouseEvent e) {  
  117.         // TODO Auto-generated method stub  
  118.           
  119.     }  
  120.   
  121.     @Override  
  122.     public void mouseExited(MouseEvent e) {  
  123.         // TODO Auto-generated method stub  
  124.           
  125.     }  
  126.   
  127. }  

首先介绍四邻域的泛洪填充算法,寻找像素点p(x, y)的上下左右四个临近像素点,如果没有

被填充,则填充它们,并且继续寻找它们的四邻域像素,直到封闭区域完全被新颜色填充。

蓝色方格为四个邻域像素, p(x, y)为当前像素点。

基于递归实现代码很简单:

[java] view plaincopy
  1. public void floodFill4(int x, int y, int newColor, int oldColor)  
  2. {  
  3.     if(x >= 0 && x < width && y >= 0 && y < height   
  4.             && getColor(x, y) == oldColor && getColor(x, y) != newColor)   
  5.     {   
  6.         setColor(x, y, newColor); //set color before starting recursion  
  7.         floodFill4(x + 1, y,     newColor, oldColor);  
  8.         floodFill4(x - 1, y,     newColor, oldColor);  
  9.         floodFill4(x,     y + 1, newColor, oldColor);  
  10.         floodFill4(x,     y - 1, newColor, oldColor);  
  11.     }     
  12. }  

八邻域的填充算法,则是在四邻域的基础上增加了左上,左下,右上,右下四个相邻像素。

并递归寻找它们的八邻域像素填充,直到区域完全被新颜色填充。


蓝色方格为四个邻域像素,黄色为左上,左下,右上,右下四个像素, p(x, y)为当前像素点。

基于递归实现的代码也很简单:

[java] view plaincopy
  1. public void floodFill8(int x, int y, int newColor, int oldColor)  
  2. {  
  3.     if(x >= 0 && x < width && y >= 0 && y < height &&   
  4.             getColor(x, y) == oldColor && getColor(x, y) != newColor)   
  5.     {   
  6.         setColor(x, y, newColor); //set color before starting recursion  
  7.         floodFill8(x + 1, y,     newColor, oldColor);  
  8.         floodFill8(x - 1, y,     newColor, oldColor);  
  9.         floodFill8(x,     y + 1, newColor, oldColor);  
  10.         floodFill8(x,     y - 1, newColor, oldColor);  
  11.         floodFill8(x + 1, y + 1, newColor, oldColor);  
  12.         floodFill8(x - 1, y - 1, newColor, oldColor);  
  13.         floodFill8(x - 1, y + 1, newColor, oldColor);  
  14.         floodFill8(x + 1, y - 1, newColor, oldColor);  
  15.     }     
  16. }  

基于扫描线实现的泛洪填充算法的主要思想是根据当前输入的点p(x, y),沿y方向分别向上

与向下扫描填充,同时向左p(x-1, y)与向右p(x+1, y)递归寻找新的扫描线,直到递归结束。

代码如下:

[java] view plaincopy
  1. public void floodFillScanLine(int x, int y, int newColor, int oldColor)  
  2. {  
  3.     if(oldColor == newColor) return;  
  4.     if(getColor(x, y) != oldColor) return;  
  5.         
  6.     int y1;  
  7.       
  8.     //draw current scanline from start position to the top  
  9.     y1 = y;  
  10.     while(y1 < height && getColor(x, y1) == oldColor)  
  11.     {  
  12.         setColor(x, y1, newColor);  
  13.         y1++;  
  14.     }      
  15.       
  16.     //draw current scanline from start position to the bottom  
  17.     y1 = y - 1;  
  18.     while(y1 >= 0 && getColor(x, y1) == oldColor)  
  19.     {  
  20.         setColor(x, y1, newColor);  
  21.         y1--;  
  22.     }  
  23.       
  24.     //test for new scanlines to the left  
  25.     y1 = y;  
  26.     while(y1 < height && getColor(x, y1) == newColor)  
  27.     {  
  28.         if(x > 0 && getColor(x - 1, y1) == oldColor)   
  29.         {  
  30.             floodFillScanLine(x - 1, y1, newColor, oldColor);  
  31.         }   
  32.         y1++;  
  33.     }  
  34.     y1 = y - 1;  
  35.     while(y1 >= 0 && getColor(x, y1) == newColor)  
  36.     {  
  37.         if(x > 0 && getColor(x - 1, y1) == oldColor)   
  38.         {  
  39.             floodFillScanLine(x - 1, y1, newColor, oldColor);  
  40.         }  
  41.         y1--;  
  42.     }   
  43.       
  44.     //test for new scanlines to the right   
  45.     y1 = y;  
  46.     while(y1 < height && getColor(x, y1) == newColor)  
  47.     {  
  48.         if(x < width - 1 && getColor(x + 1, y1) == oldColor)   
  49.         {             
  50.             floodFillScanLine(x + 1, y1, newColor, oldColor);  
  51.         }   
  52.         y1++;  
  53.     }  
  54.     y1 = y - 1;  
  55.     while(y1 >= 0 && getColor(x, y1) == newColor)  
  56.     {  
  57.         if(x < width - 1 && getColor(x + 1, y1) == oldColor)   
  58.         {  
  59.             floodFillScanLine(x + 1, y1, newColor, oldColor);  
  60.         }  
  61.         y1--;  
  62.     }  
  63. }  

基于递归实现的泛洪填充算法有个致命的缺点,就是对于大的区域填充时可能导致JAVA栈溢出

错误,对最后一种基于扫描线的算法,实现了一种非递归的泛洪填充算法。

[java] view plaincopy
  1. public void floodFillScanLineWithStack(int x, int y, int newColor, int oldColor)  
  2. {  
  3.     if(oldColor == newColor) {  
  4.         System.out.println("do nothing !!!, filled area!!");  
  5.         return;  
  6.     }  
  7.     emptyStack();  
  8.       
  9.     int y1;   
  10.     boolean spanLeft, spanRight;  
  11.     push(x, y);  
  12.       
  13.     while(true)  
  14.     {      
  15.         x = popx();  
  16.         if(x == -1return;  
  17.         y = popy();  
  18.         y1 = y;  
  19.         while(y1 >= 0 && getColor(x, y1) == oldColor) y1--; // go to line top/bottom  
  20.         y1++; // start from line starting point pixel  
  21.         spanLeft = spanRight = false;  
  22.         while(y1 < height && getColor(x, y1) == oldColor)  
  23.         {  
  24.             setColor(x, y1, newColor);  
  25.             if(!spanLeft && x > 0 && getColor(x - 1, y1) == oldColor)// just keep left line once in the stack  
  26.             {  
  27.                 push(x - 1, y1);  
  28.                 spanLeft = true;  
  29.             }  
  30.             else if(spanLeft && x > 0 && getColor(x - 1, y1) != oldColor)  
  31.             {  
  32.                 spanLeft = false;  
  33.             }  
  34.             if(!spanRight && x < width - 1 && getColor(x + 1, y1) == oldColor) // just keep right line once in the stack  
  35.             {  
  36.                 push(x + 1, y1);  
  37.                 spanRight = true;  
  38.             }  
  39.             else if(spanRight && x < width - 1 && getColor(x + 1, y1) != oldColor)  
  40.             {  
  41.                 spanRight = false;  
  42.             }   
  43.             y1++;  
  44.         }  
  45.     }  
  46.       
  47. }  
运行效果:


算法类源代码如下:

[java] view plaincopy
  1. package com.gloomyfish.paint.fill;  
  2.   
  3. import java.awt.image.BufferedImage;  
  4.   
  5. import com.gloomyfish.filter.study.AbstractBufferedImageOp;  
  6.   
  7. public class FloodFillAlgorithm extends AbstractBufferedImageOp {  
  8.   
  9.     private BufferedImage inputImage;  
  10.     private int[] inPixels;  
  11.     private int width;  
  12.     private int height;  
  13.       
  14.     //  stack data structure  
  15.     private int maxStackSize = 500// will be increased as needed  
  16.     private int[] xstack = new int[maxStackSize];  
  17.     private int[] ystack = new int[maxStackSize];  
  18.     private int stackSize;  
  19.   
  20.     public FloodFillAlgorithm(BufferedImage rawImage) {  
  21.         this.inputImage = rawImage;  
  22.         width = rawImage.getWidth();  
  23.         height = rawImage.getHeight();  
  24.         inPixels = new int[width*height];  
  25.         getRGB(rawImage, 00, width, height, inPixels );  
  26.     }  
  27.   
  28.     public BufferedImage getInputImage() {  
  29.         return inputImage;  
  30.     }  
  31.   
  32.     public void setInputImage(BufferedImage inputImage) {  
  33.         this.inputImage = inputImage;  
  34.     }  
  35.       
  36.     public int getColor(int x, int y)  
  37.     {  
  38.         int index = y * width + x;  
  39.         return inPixels[index];  
  40.     }  
  41.       
  42.     public void setColor(int x, int y, int newColor)  
  43.     {  
  44.         int index = y * width + x;  
  45.         inPixels[index] = newColor;  
  46.     }  
  47.       
  48.     public void updateResult()  
  49.     {  
  50.         setRGB( inputImage, 00, width, height, inPixels );  
  51.     }  
  52.       
  53.     /** 
  54.      * it is very low calculation speed and cause the stack overflow issue when fill  
  55.      * some big area and irregular shape. performance is very bad. 
  56.      *  
  57.      * @param x 
  58.      * @param y 
  59.      * @param newColor 
  60.      * @param oldColor 
  61.      */  
  62.     public void floodFill4(int x, int y, int newColor, int oldColor)  
  63.     {  
  64.         if(x >= 0 && x < width && y >= 0 && y < height   
  65.                 && getColor(x, y) == oldColor && getColor(x, y) != newColor)   
  66.         {   
  67.             setColor(x, y, newColor); //set color before starting recursion  
  68.             floodFill4(x + 1, y,     newColor, oldColor);  
  69.             floodFill4(x - 1, y,     newColor, oldColor);  
  70.             floodFill4(x,     y + 1, newColor, oldColor);  
  71.             floodFill4(x,     y - 1, newColor, oldColor);  
  72.         }     
  73.     }  
  74.     /** 
  75.      *  
  76.      * @param x 
  77.      * @param y 
  78.      * @param newColor 
  79.      * @param oldColor 
  80.      */  
  81.     public void floodFill8(int x, int y, int newColor, int oldColor)  
  82.     {  
  83.         if(x >= 0 && x < width && y >= 0 && y < height &&   
  84.                 getColor(x, y) == oldColor && getColor(x, y) != newColor)   
  85.         {   
  86.             setColor(x, y, newColor); //set color before starting recursion  
  87.             floodFill8(x + 1, y,     newColor, oldColor);  
  88.             floodFill8(x - 1, y,     newColor, oldColor);  
  89.             floodFill8(x,     y + 1, newColor, oldColor);  
  90.             floodFill8(x,     y - 1, newColor, oldColor);  
  91.             floodFill8(x + 1, y + 1, newColor, oldColor);  
  92.             floodFill8(x - 1, y - 1, newColor, oldColor);  
  93.             floodFill8(x - 1, y + 1, newColor, oldColor);  
  94.             floodFill8(x + 1, y - 1, newColor, oldColor);  
  95.         }     
  96.     }  
  97.       
  98.     /** 
  99.      *  
  100.      * @param x 
  101.      * @param y 
  102.      * @param newColor 
  103.      * @param oldColor 
  104.      */  
  105.     public void floodFillScanLine(int x, int y, int newColor, int oldColor)  
  106.     {  
  107.         if(oldColor == newColor) return;  
  108.         if(getColor(x, y) != oldColor) return;  
  109.             
  110.         int y1;  
  111.           
  112.         //draw current scanline from start position to the top  
  113.         y1 = y;  
  114.         while(y1 < height && getColor(x, y1) == oldColor)  
  115.         {  
  116.             setColor(x, y1, newColor);  
  117.             y1++;  
  118.         }      
  119.           
  120.         //draw current scanline from start position to the bottom  
  121.         y1 = y - 1;  
  122.         while(y1 >= 0 && getColor(x, y1) == oldColor)  
  123.         {  
  124.             setColor(x, y1, newColor);  
  125.             y1--;  
  126.         }  
  127.           
  128.         //test for new scanlines to the left  
  129.         y1 = y;  
  130.         while(y1 < height && getColor(x, y1) == newColor)  
  131.         {  
  132.             if(x > 0 && getColor(x - 1, y1) == oldColor)   
  133.             {  
  134.                 floodFillScanLine(x - 1, y1, newColor, oldColor);  
  135.             }   
  136.             y1++;  
  137.         }  
  138.         y1 = y - 1;  
  139.         while(y1 >= 0 && getColor(x, y1) == newColor)  
  140.         {  
  141.             if(x > 0 && getColor(x - 1, y1) == oldColor)   
  142.             {  
  143.                 floodFillScanLine(x - 1, y1, newColor, oldColor);  
  144.             }  
  145.             y1--;  
  146.         }   
  147.           
  148.         //test for new scanlines to the right   
  149.         y1 = y;  
  150.         while(y1 < height && getColor(x, y1) == newColor)  
  151.         {  
  152.             if(x < width - 1 && getColor(x + 1, y1) == oldColor)   
  153.             {             
  154.                 floodFillScanLine(x + 1, y1, newColor, oldColor);  
  155.             }   
  156.             y1++;  
  157.         }  
  158.         y1 = y - 1;  
  159.         while(y1 >= 0 && getColor(x, y1) == newColor)  
  160.         {  
  161.             if(x < width - 1 && getColor(x + 1, y1) == oldColor)   
  162.             {  
  163.                 floodFillScanLine(x + 1, y1, newColor, oldColor);  
  164.             }  
  165.             y1--;  
  166.         }  
  167.     }  
  168.       
  169.     public void floodFillScanLineWithStack(int x, int y, int newColor, int oldColor)  
  170.     {  
  171.         if(oldColor == newColor) {  
  172.             System.out.println("do nothing !!!, filled area!!");  
  173.             return;  
  174.         }  
  175.         emptyStack();  
  176.           
  177.         int y1;   
  178.         boolean spanLeft, spanRight;  
  179.         push(x, y);  
  180.           
  181.         while(true)  
  182.         {      
  183.             x = popx();  
  184.             if(x == -1return;  
  185.             y = popy();  
  186.             y1 = y;  
  187.             while(y1 >= 0 && getColor(x, y1) == oldColor) y1--; // go to line top/bottom  
  188.             y1++; // start from line starting point pixel  
  189.             spanLeft = spanRight = false;  
  190.             while(y1 < height && getColor(x, y1) == oldColor)  
  191.             {  
  192.                 setColor(x, y1, newColor);  
  193.                 if(!spanLeft && x > 0 && getColor(x - 1, y1) == oldColor)// just keep left line once in the stack  
  194.                 {  
  195.                     push(x - 1, y1);  
  196.                     spanLeft = true;  
  197.                 }  
  198.                 else if(spanLeft && x > 0 && getColor(x - 1, y1) != oldColor)  
  199.                 {  
  200.                     spanLeft = false;  
  201.                 }  
  202.                 if(!spanRight && x < width - 1 && getColor(x + 1, y1) == oldColor) // just keep right line once in the stack  
  203.                 {  
  204.                     push(x + 1, y1);  
  205.                     spanRight = true;  
  206.                 }  
  207.                 else if(spanRight && x < width - 1 && getColor(x + 1, y1) != oldColor)  
  208.                 {  
  209.                     spanRight = false;  
  210.                 }   
  211.                 y1++;  
  212.             }  
  213.         }  
  214.           
  215.     }  
  216.       
  217.     private void emptyStack() {  
  218.         while(popx() != - 1) {  
  219.             popy();  
  220.         }  
  221.         stackSize = 0;  
  222.     }  
  223.   
  224.     final void push(int x, int y) {  
  225.         stackSize++;  
  226.         if (stackSize==maxStackSize) {  
  227.             int[] newXStack = new int[maxStackSize*2];  
  228.             int[] newYStack = new int[maxStackSize*2];  
  229.             System.arraycopy(xstack, 0, newXStack, 0, maxStackSize);  
  230.             System.arraycopy(ystack, 0, newYStack, 0, maxStackSize);  
  231.             xstack = newXStack;  
  232.             ystack = newYStack;  
  233.             maxStackSize *= 2;  
  234.         }  
  235.         xstack[stackSize-1] = x;  
  236.         ystack[stackSize-1] = y;  
  237.     }  
  238.       
  239.     final int popx() {  
  240.         if (stackSize==0)  
  241.             return -1;  
  242.         else  
  243.             return xstack[stackSize-1];  
  244.     }  
  245.   
  246.     final int popy() {  
  247.         int value = ystack[stackSize-1];  
  248.         stackSize--;  
  249.         return value;  
  250.     }  
  251.   
  252.     @Override  
  253.     public BufferedImage filter(BufferedImage src, BufferedImage dest) {  
  254.         // TODO Auto-generated method stub  
  255.         return null;  
  256.     }  
  257.   
  258. }  

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
[git] warning: LF will be replaced by CRLF | fatal: CRLF would be replaced by LF[ git 处理和修改行结束符(CRLF和LF)]
  我自己的设置是: [core] autocrlf = false[core] safecrlf = true 取消自动转换CRLF(上图中选的是commit as is),但是有提交前混用检查 本人用的是WINDOWS下的PHPSTORM开发的PHP       遇到这两个错误,是因为Git的换行符检查功能。
1107 0
hive Illegal Operation state transition from CLOSED to ERROR的处理
异常堆栈如下: 2015-11-24 16:49:11,495 ERROR org.apache.hive.service.cli.operation.Operation: Error running hive query:org.
1673 0
Algorithm:C++语言实现之字符串相关算法(字符串的循环左移、字符串的全排列、带有同个字符的全排列、串匹配问题的BF算法和KMP算法)(二)
Algorithm:C++语言实现之字符串相关算法(字符串的循环左移、字符串的全排列、带有同个字符的全排列、串匹配问题的BF算法和KMP算法)
26 0
Algorithm:C++语言实现之字符串相关算法(字符串的循环左移、字符串的全排列、带有同个字符的全排列、串匹配问题的BF算法和KMP算法)(一)
Algorithm:C++语言实现之字符串相关算法(字符串的循环左移、字符串的全排列、带有同个字符的全排列、串匹配问题的BF算法和KMP算法)
32 0
ML之DR之PCA:利用PCA对手写数字图片识别数据集进行降维处理(理解PCA)
ML之DR之PCA:利用PCA对手写数字图片识别数据集进行降维处理(理解PCA)
16 0
Algorithm:C++语言实现之Hash哈希算法相关(dbj2、sdbm、MurmurHash)
Algorithm:C++语言实现之Hash哈希算法相关(dbj2、sdbm、MurmurHash)
34 0
基于对象存储 OSS 的智能数据分析处理框架和功能
今年参加了 2019 全球闪存峰会(Flash Memory World),分享了“基于云存储的智能数据分析处理架构”,重点介绍在对象存储 OSS 之上的数据处理功能,现整理相关内容和大家探讨。
2140 0
+关注
毛毛虫的爹
好好学习,天天向上
625
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载