最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java獲取彩色圖像中的主色彩的實(shí)例代碼

 更新時(shí)間:2018年05月15日 15:21:24   投稿:yanan  
這篇文章主要介紹了Java獲取彩色圖像中的主色彩的實(shí)例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

本文講述了Java獲取彩色圖像中的主色彩的實(shí)例代碼。分享給大家供大家參考,具體如下:

一:基本思路

對(duì)于一張RGB色彩空間的彩色圖像,很多時(shí)間我們想通過程序獲得該圖像有幾種主要的色彩,但是對(duì)一般圖像來說,在色彩交界處都是通過像素混合來實(shí)現(xiàn)自然過渡,所以直接掃描圖像的像素值,得到的不同顏色值可能多達(dá)上百中,而實(shí)際上圖像可能只有3~4種的主要色彩,如何去掉那些混合顏色,準(zhǔn)確提取出來這3~4中的主色彩,根據(jù)一般圖像的特征,圖像在不同色彩的邊界處混合不同的顏色值,此可以視為圖像的邊緣特性之一,因此可以根據(jù)簡(jiǎn)單的邊緣梯度算法實(shí)現(xiàn)這些混合像素的提取得到輸出的像素值數(shù)組,然后掃描每個(gè)像素值,尋找指定半徑參數(shù)R周圍的像素,發(fā)現(xiàn)為零,而且距離中心像素最近的像素點(diǎn)的值做為中心像素的像素值,掃描結(jié)束以后輸出像素?cái)?shù)組,然后對(duì)數(shù)組線性掃描,即可得到圖片的主要色彩RGB值。

二:實(shí)現(xiàn)步驟
1.      輸入圖像數(shù)組,對(duì)彩色圖像灰度化;
2.      對(duì)灰度化以后的圖像,計(jì)算圖像梯度,這里使用sobol算子;
3.      對(duì)得到每一個(gè)非零像素點(diǎn)實(shí)現(xiàn)半徑為R的范圍內(nèi)的掃描,找出與之最相近的為零的原像素值;
4.      對(duì)得到數(shù)組進(jìn)行簡(jiǎn)單的掃描,得到主色彩。

其中參數(shù)R是要根據(jù)不同應(yīng)用場(chǎng)景,找到最合適的值。理論上圖像越大,R的取值也應(yīng)該越大,否則算法會(huì)失準(zhǔn)。

三:原圖及運(yùn)行效果

原圖

算法運(yùn)行之后提取到四種主要色彩

四:算法實(shí)現(xiàn)源代碼

public static BufferedImage removeBlendPixels(BufferedImage image, int raidus) { 
  int width = image.getWidth(); 
  int height = image.getHeight(); 
  int[] pixels = new int[width * height]; 
  getRGB(image, 0, 0, width, height, pixels); 
  // 創(chuàng)建處理結(jié)果 
  BufferedImage resultImg = createCompatibleDestImage(image, null); 
  setRGB(resultImg, 0, 0, width, height, pixels); 
  // 灰度化與梯度求取 
  byte[] grayData = getGrayData(pixels, width, height); 
  byte[] binaryData = getGrident(grayData, width, height); 
  int index = 0; 
  for (int row = 1; row < height - 1; row++) { 
   for (int col = 1; col < width - 1; col++) { 
    index = row * width + col; 
    int pixel = (binaryData[index] & 0xff); 
    if (pixel > 0) { 
     // 半徑掃描操作 
     int mindis = Integer.MAX_VALUE; 
     int minrow = -1; 
     int mincol = -1; 
     int nr = 0; 
     int nc = 0; 
     int index2 = 0; 
     for (int subrow = -raidus; subrow <= raidus; subrow++) { 
      nr = row + subrow; 
      if (nr < 0 || nr >= height) { 
       continue; 
      } 
      for (int subcol = -raidus; subcol <= raidus; subcol++) { 
       nc = col + subcol; 
       if (nc < 0 || nc >= width) { 
        continue; 
       } 
       index2 = nr * width + nc; 
       int value = (binaryData[index2] & 0xff); 
       if (value == 0) { 
        int distance = distanceColor(image.getRGB(nc, nr), image.getRGB(col, row)); 
        if (distance < mindis) { 
         mindis = distance; 
         minrow = nr; 
         mincol = nc; 
        } 
       } 
      } 
     } 
     resultImg.setRGB(col, row, image.getRGB(mincol, minrow)); 
    } 
   } 
  } 
  return resultImg; 
 } 
 public static int distanceColor(int rgb, int rgb2) { 
  // Color one 
  int r1 = (rgb >> 16) & 0xff; 
  int g1 = (rgb >> 8) & 0xff; 
  int b1 = rgb & 0xff; 
  // Color two 
  int r2 = (rgb2 >> 16) & 0xff; 
  int g2 = (rgb2 >> 8) & 0xff; 
  int b2 = rgb2 & 0xff; 
  // distance 
  int rr = r1 - r2; 
  int gg = g1 - g2; 
  int bb = b1 - b2; 
  int sum = (int) Math.sqrt(rr * rr + gg * gg + bb * bb); 
  return sum; 
 } 
 public static byte[] getGrayData(int[] inPixels, int width, int height) { 
  // 圖像灰度化 
  byte[] outPixels = new byte[width * height]; 
  int index = 0; 
  for (int row = 0; row < height; row++) { 
   int tr = 0, tg = 0, tb = 0; 
   for (int col = 0; col < width; col++) { 
    index = row * width + col; 
    tr = (inPixels[index] >> 16) & 0xff; 
    tg = (inPixels[index] >> 8) & 0xff; 
    tb = inPixels[index] & 0xff; 
    int gray = (int) (0.299 * tr + 0.587 * tg + 0.114 * tb); 
    outPixels[index] = (byte) (gray & 0xff); 
   } 
  } 
  return outPixels; 
 } 
 public static byte[] getGrident(byte[] inPixels, int width, int height) { 
  byte[] outPixels = new byte[width * height]; 
  int index = 0; 
  for (int row = 0; row < height; row++) { 
   int tr = 0; 
   for (int col = 0; col < width; col++) { 
    if (row == 0 || col == 0 || (row == height - 1) || (col == width - 1)) { 
     index = row * width + col; 
     outPixels[index] = (byte) (0x00); 
     continue; 
    } 
    int xg = 0, yg = 0; 
    for (int sr = -1; sr <= 1; sr++) { 
     for (int sc = -1; sc <= 1; sc++) { 
      int nrow = row + sr; 
      int ncol = col + sc; 
      if (nrow < 0 || nrow >= height) { 
       nrow = 0; 
      } 
      if (ncol < 0 || ncol >= width) { 
       ncol = 0; 
      } 
      index = nrow * width + ncol; 
      tr = (inPixels[index] & 0xff); 
      xg += X_SOBEL[sr + 1][sc + 1] * tr; 
      yg += Y_SOBEL[sr + 1][sc + 1] * tr; 
     } 
    } 
    index = row * width + col; 
    int g = (int) Math.sqrt(xg * xg + yg * yg); 
    outPixels[index] = (byte) (clamp(g) & 0xff); 
   } 
  } 
  return outPixels; 
 } 

需要定義的常量值如下:

public static final int[][] X_SOBEL = new int[][] { { -1, -2, -1 }, { 0, 0, 0 }, { 1, 2, 1 } }; 
public static final int[][] Y_SOBEL = new int[][] { { -1, 0, 1 }, { -2, 0, 2 }, { -1, 0, 1 } }; 
public static final int BLOCK_PIXEL_RADIUS = 5; 

梯度求取使用是sobol算子,對(duì)處理以后的BufferedImage對(duì)象掃描獲取主色彩的代碼如下:

int width = result.getWidth(); 
int height = result.getHeight(); 
Map<Integer, Integer> colorIndexMap = new HashMap<Integer, Integer>(); 
for (int row = 0; row < height; row++) { 
 for (int col = 0; col < width; col++) { 
  int pixelValue = result.getRGB(col, row); 
  if (!colorIndexMap.containsKey(pixelValue)) { 
   colorIndexMap.put(pixelValue, pixelValue); 
  } 
 } 
} 
// now scan pixel value 
// return result 
System.out.println("number of color = " + colorIndexMap.size()); 
return colorIndexMap.keySet().toArray(new Integer[0]);

測(cè)試代碼如下:

public static void main(String[] args) { 
 File file = new File("D:\\gloomyfish\\bigmonkey.png"); 
 File resultFile = new File("D:\\gloomyfish\\result.png"); 
 try { 
  BufferedImage image = ImageIO.read(file); 
  BufferedImage result = removeBlendPixels(image, BLOCK_PIXEL_RADIUS); 
  ImageIO.write(result, "png", resultFile); 
  Integer[] colors = extractColors(result); 
  System.out.println("total colors : " + colors.length); 
 } catch (IOException e) { 
  e.printStackTrace(); 
 } 
} 

 注意:主要的關(guān)鍵在于對(duì)待處理圖像輸入正確大小的半徑,這個(gè)半徑大小跟圖像實(shí)際大小相關(guān),而且算法可以近一步優(yōu)化成不依賴半徑參數(shù)的版本,知道找到等于零的像素為止。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java如何把int類型轉(zhuǎn)換成byte

    Java如何把int類型轉(zhuǎn)換成byte

    這篇文章主要介紹了Java如何把int類型轉(zhuǎn)換成byte,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • MyBatis通過BATCH批量提交的方法

    MyBatis通過BATCH批量提交的方法

    今天小編就為大家分享一篇關(guān)于MyBatis通過BATCH批量提交的方法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • Java中抽象類用法與注意點(diǎn)實(shí)例詳解

    Java中抽象類用法與注意點(diǎn)實(shí)例詳解

    這篇文章主要介紹了Java中抽象類用法與注意點(diǎn),結(jié)合實(shí)例形式詳細(xì)分析了java抽象類的定義、使用及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2019-08-08
  • 原生java代碼實(shí)現(xiàn)碼云第三方驗(yàn)證登錄的示例代碼

    原生java代碼實(shí)現(xiàn)碼云第三方驗(yàn)證登錄的示例代碼

    這篇文章主要介紹了原生java代碼實(shí)現(xiàn)碼云第三方驗(yàn)證登錄的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • JAVA Vector源碼解析和示例代碼

    JAVA Vector源碼解析和示例代碼

    本文的學(xué)習(xí)方式是先對(duì)JAVA Vector有個(gè)整體認(rèn)識(shí),然后再學(xué)習(xí)它的源碼,最后再通過實(shí)例來學(xué)會(huì)使用。
    2013-11-11
  • 淺談mybatis 樂觀鎖實(shí)現(xiàn),解決并發(fā)問題

    淺談mybatis 樂觀鎖實(shí)現(xiàn),解決并發(fā)問題

    這篇文章主要介紹了淺談mybatis 樂觀鎖實(shí)現(xiàn),解決并發(fā)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • 親測(cè)解決,nacos下線失敗問題

    親測(cè)解決,nacos下線失敗問題

    這篇文章主要介紹了親測(cè)解決,nacos下線失敗問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • 淺談FileItem類的常用方法

    淺談FileItem類的常用方法

    下面小編就為大家?guī)硪黄獪\談FileItem類的常用方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-08-08
  • Springboot 配置RabbitMQ文檔的方法步驟

    Springboot 配置RabbitMQ文檔的方法步驟

    這篇文章主要介紹了Springboot 配置RabbitMQ文檔的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • jdbcTemplate使用方法實(shí)例解析

    jdbcTemplate使用方法實(shí)例解析

    這篇文章主要介紹了jdbcTemplate使用方法實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02

最新評(píng)論

黎城县| 讷河市| 辽阳县| 增城市| 兰坪| 多伦县| 定远县| 宁都县| 利津县| 浮梁县| 新安县| 南安市| 高青县| 开原市| 三江| 佛教| 西乌| 中西区| 旬邑县| 澄城县| 义马市| 扎兰屯市| 鄂尔多斯市| 井陉县| 江油市| 三门峡市| 杭锦旗| 清镇市| 册亨县| 游戏| 玉门市| 蒙山县| 澄迈县| 尚义县| 柳州市| 南川市| 泌阳县| 敦煌市| 嫩江县| 普格县| 泰来县|