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

Java實(shí)現(xiàn)去除文檔陰影的示例代碼

 更新時(shí)間:2022年12月08日 09:14:29   作者:ZackSock  
文稿掃描大家用的都比較頻繁、想是各種證件、文件都可以通過(guò)掃描文稿功能保存到手機(jī)。相比直接拍照,在掃描文稿時(shí),程序會(huì)對(duì)圖像進(jìn)行一些矯正。比如去除陰影、修正傾斜、旋轉(zhuǎn)矯正等。進(jìn)行這些處理后的圖片要更加容易識(shí)別。今天就來(lái)討論一下去除陰影的操作

一、前言

文稿掃描大家用的都比較頻繁、想是各種證件、文件都可以通過(guò)掃描文稿功能保存到手機(jī)。相比直接拍照,在掃描文稿時(shí),程序會(huì)對(duì)圖像進(jìn)行一些矯正。比如去除陰影、修正傾斜、旋轉(zhuǎn)矯正等。進(jìn)行這些處理后的圖片要更加容易識(shí)別。今天就來(lái)討論以下去除陰影的操作。

二、實(shí)現(xiàn)原理

1. 圖像

在開始實(shí)現(xiàn)前,我們來(lái)了解一些圖像相關(guān)的知識(shí)。這里討論RGB圖像,也就是我們俗稱的彩色的圖像。圖像可以被看作是一個(gè)height×width的數(shù)組,每一個(gè)數(shù)表示一個(gè)像素。如果是彩色的圖像,每個(gè)像素會(huì)包含RBG三個(gè)值,最低字節(jié)表示G、次低字節(jié)表示B、第三字節(jié)表示R。

比如像素值為:

0x00ff00

其RBG值分別為:

R: 0x00
G: 0xff
B: 0x00

如果想要從原像素中取RGB的值,可以使用按位與操作,示例如下:

// pixel是從圖像中取出來(lái)的數(shù)
int[] rgb = new int[3];
rgb[0] = (pixel & 0xff0000) >> 16;
rgb[1] = (pixel & 0xff00) >> 8;
rgb[2] = (pixel & 0xff); 

因?yàn)楂@取R和G的時(shí)候,保留的是高位,我們希望得到的是一個(gè)低位的數(shù)據(jù),因此向右移一定位。

2. 灰度轉(zhuǎn)換

有時(shí)候,為了方便處理會(huì)把圖像轉(zhuǎn)換成灰度圖像。轉(zhuǎn)換成灰度圖像的方法有很多,一種非常簡(jiǎn)單的辦法就是讓rgb三個(gè)通道都為同樣的值,這個(gè)值就是rgb三個(gè)值的均值。

3.閾值處理

閾值處理是今天關(guān)鍵部分,閾值處理的思想非常簡(jiǎn)單,就是當(dāng)圖像像素值大于閾值時(shí)將其處理為最大值,當(dāng)像素小于等于閾值時(shí)將其處理為0。這樣可以得到一張完全的黑白圖像。

在文稿中,文字部分可以看作是黑色,背景部分可以看作是白色,而陰影則是介于黑白之間的值。如果想要去除陰影,則需要對(duì)圖像進(jìn)行閾值處理,把閾值設(shè)定為小于陰影的值。比如下圖:

左圖是原圖,其中灰色部分為陰影,需要去除。這時(shí)我們對(duì)圖像進(jìn)行閾值處理,把閾值設(shè)定為50,那么陰影部分就會(huì)被設(shè)置成255,文字部分和背景部分變換都不大,這樣就實(shí)現(xiàn)了文稿的陰影去除工作。

三、代碼實(shí)現(xiàn)

1.讀取圖像

首先來(lái)看看如何讀取圖像以及如何訪問(wèn)圖像的像素,這里使用ImageIO類。代碼如下:

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;

public class DocumentDealing {

    public static void main(String[] args) throws Exception {
        String imagePath = "D:/images/imgs/10000.jpeg";
        BufferedImage bi = ImageIO.read(new File(imagePath));
        //獲取圖片寬高
        int width = bi.getWidth();
        int height = bi.getHeight();
        System.out.println("width:" + width + ",height:" + height);
        //獲取坐標(biāo)為(0, 0)位置的像素
        int pixel = bi.getRGB(0, 0);
        System.out.println("pixel" + pixel);
        //獲取rgb值
        int[] rgb = new int[3];
        rgb[0] = (pixel & 0xff0000) >> 16;
        rgb[1] = (pixel & 0xff00) >> 8;
        rgb[2] = pixel & 0xff;
        System.out.println(
                "r:" + rgb[0] +
                        "\tg:" + rgb[1] +
                        "\tb:" + rgb[2]
        );
    }

    public static int[] getRgb(BufferedImage bi, int x, int y) {
        int[] rgb = new int[3];
        int pixel = bi.getRGB(x, y);
        rgb[0] = (pixel & 0xff0000) >> 16;
        rgb[1] = (pixel & 0xff00) >> 8;
        rgb[2] = (pixel & 0xff);
        return rgb;
    }

}

我們可以通過(guò)下面代碼讀取圖片,其中imagePath是圖片路徑:

BufferedImage bi = ImageIO.read(new File(imagePath));

BufferedImage可以獲取圖片的寬、高、某個(gè)點(diǎn)的像素等。為了方便,編寫一個(gè)getRgb來(lái)把pixel轉(zhuǎn)成一個(gè)rgb數(shù)組。代碼輸出結(jié)果如下:

width:400,height:400
pixel-2853206
r:212    g:118    b:170

2.閾值處理

知道了上面的基本操作后,就可以開始進(jìn)行閾值處理了。閾值處理就是求rgb均值mean,如果mean大于閾值,則把像素設(shè)置為0xffffff,否則設(shè)置為0。具體代碼如下:

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;

public class DocumentDealing {

    public static void main(String[] args) throws Exception {
        String imagePath = "C:/Users/Administrator/Desktop/document.jpg";
        threshold(imagePath, "result.jpg", 50);
    }

    public static void threshold(String imagePath, String savePath, int threshold) throws Exception{
      	//讀取圖片
        BufferedImage bi = ImageIO.read(new File(imagePath));
        //讀取寬高
      	int width = bi.getWidth();
        int height = bi.getHeight();
      	//遍歷圖片像素
        for(int y = 0; y < height; y ++){
            for(int x = 0; x < width; x ++){
                int[] rgb = getRgb(bi, x, y);
              	//計(jì)算rgb均值
                int grayScale = (rgb[0] + rgb[1] + rgb[2]) / 3;
              	//如果均值大于閾值,則賦值將該像素設(shè)置為0xffffff(全白),否則賦值為0(全黑)
                if(grayScale > threshold){
                  	bi.setRgb(x, y, 0xffffff);
                }else{
                  	bi.setRgb(x, y, 0);
                }
            }
        }
      	//保存圖片
        ImageIO.write(bi, "jpg", new File(savePath));
    }

    public static int[] getRgb(BufferedImage bi, int x, int y){
        int[] rgb = new int[3];
        int pixel = bi.getRGB(x, y);
        rgb[0] = (pixel & 0xff0000) >> 16;
        rgb[1] = (pixel & 0xff00) >> 8;
        rgb[2] = (pixel & 0xff);
        return rgb;
    }

}

下圖是原圖和處理后的結(jié)果:

左圖中有兩處陰影,右側(cè)則去除了陰影。最終效果圖與設(shè)定的閾值有關(guān)系,當(dāng)閾值設(shè)置不恰當(dāng)時(shí),會(huì)導(dǎo)致結(jié)果圖比原圖更糟糕,或者導(dǎo)致最終文字目標(biāo)也被去除了。這里可以用循環(huán)來(lái)解決,代碼如下:

public static void main(String[] args) throws Exception {
    String imagePath = "C:/Users/Administrator/Desktop/document.jpg";
      for (int i = 50; i < 127; i++) {
        threshold(imagePath, "imgs/result" + i + ".jpg", i);
      }
}

大家可以自行測(cè)試。有時(shí)候之間閾值處理不能很好的去除陰影,這個(gè)時(shí)候會(huì)結(jié)合一些其它辦法。包括濾波操作、形態(tài)學(xué)處理等。

到此這篇關(guān)于Java實(shí)現(xiàn)去除文檔陰影的示例代碼的文章就介紹到這了,更多相關(guān)Java去除文檔陰影內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 在IDEA中配置tomcat并創(chuàng)建tomcat項(xiàng)目的圖文教程

    在IDEA中配置tomcat并創(chuàng)建tomcat項(xiàng)目的圖文教程

    這篇文章主要介紹了在IDEA中配置tomcat并創(chuàng)建tomcat項(xiàng)目的圖文教程,需要的朋友可以參考下
    2020-07-07
  • 詳解spring整合hibernate的方法

    詳解spring整合hibernate的方法

    這篇文章主要介紹了spring整合hibernate的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • 詳解Java8與Runtime.getRuntime().availableProcessors()

    詳解Java8與Runtime.getRuntime().availableProcessors()

    這篇文章主要介紹了詳解Java8與Runtime.getRuntime().availableProcessors(),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • SpringBoot項(xiàng)目多層級(jí)多環(huán)境yml設(shè)計(jì)詳解

    SpringBoot項(xiàng)目多層級(jí)多環(huán)境yml設(shè)計(jì)詳解

    這篇文章主要為大家介紹了SpringBoot項(xiàng)目多層級(jí)多環(huán)境yml設(shè)計(jì)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Java創(chuàng)建對(duì)象之顯示創(chuàng)建與隱式創(chuàng)建

    Java創(chuàng)建對(duì)象之顯示創(chuàng)建與隱式創(chuàng)建

    在本篇文章中,小編會(huì)帶大家學(xué)習(xí)面向?qū)ο笾嘘P(guān)于對(duì)象的創(chuàng)建之顯示創(chuàng)建和隱式創(chuàng)建,其實(shí)類和對(duì)象作為面向?qū)ο笾凶罨镜?,也是最重要?需要的朋友可以參考下
    2023-05-05
  • Redis之SpringDataRedis用法詳解

    Redis之SpringDataRedis用法詳解

    這篇文章主要介紹了Redis之SpringDataRedis的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • 代理模式之Java動(dòng)態(tài)代理實(shí)現(xiàn)方法

    代理模式之Java動(dòng)態(tài)代理實(shí)現(xiàn)方法

    今天一個(gè)偶然的機(jī)會(huì)我突然想看看JDK的動(dòng)態(tài)代理,因?yàn)橐郧耙仓酪稽c(diǎn),而且只是簡(jiǎn)單的想測(cè)試一下使用,使用很快里就寫好了這么幾個(gè)接口和類,需要的朋友可以參考下
    2012-11-11
  • javaweb實(shí)戰(zhàn)之商城項(xiàng)目開發(fā)(二)

    javaweb實(shí)戰(zhàn)之商城項(xiàng)目開發(fā)(二)

    這篇文章主要針對(duì)javaweb商城項(xiàng)目開發(fā)進(jìn)行實(shí)戰(zhàn)演習(xí),利用mybatis創(chuàng)建DAO層,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-02-02
  • Java中序列化和反序列化的完整講解

    Java中序列化和反序列化的完整講解

    序列化是將對(duì)象轉(zhuǎn)換成二進(jìn)制字節(jié)流的過(guò)程;反序列化是從二進(jìn)制字節(jié)流中恢復(fù)對(duì)象的過(guò)程。文中將為大家詳細(xì)講講二者的原理與實(shí)現(xiàn),需要的可以參考一下
    2022-11-11
  • Java讀取Properties文件幾種方法總結(jié)

    Java讀取Properties文件幾種方法總結(jié)

    這篇文章主要介紹了 Java讀取Properties文件幾種方法總結(jié)的相關(guān)資料,需要的朋友可以參考下
    2017-04-04

最新評(píng)論

乃东县| 河津市| 金溪县| 容城县| 河南省| 东兰县| 茌平县| 剑阁县| 巴楚县| 保亭| 柳林县| 青州市| 新乡市| 鹤壁市| 伊川县| 婺源县| 滦平县| 古蔺县| 江口县| 南宫市| 元氏县| 林芝县| 文昌市| 广灵县| 普洱| 个旧市| 陵川县| 曲麻莱县| 余庆县| 汨罗市| 友谊县| 柏乡县| 沾化县| 陆川县| 西盟| 临泉县| 永济市| 福建省| 石泉县| 金山区| 西吉县|