一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務(wù)器之家 - 編程語言 - Java教程 - 使用java + OpenCV破解頂象面積驗證碼的示例

使用java + OpenCV破解頂象面積驗證碼的示例

2021-08-02 11:48香芋味的貓 Java教程

這篇文章主要介紹了使用java + OpenCV破解頂象面積驗證碼的示例,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

前言

使用java + OpenCV破解頂象面積驗證碼的示例

我們又來破解驗證碼啦,今天上場的是–頂象面積驗證碼

使用java + OpenCV破解頂象面積驗證碼的示例

根據(jù)場景來看,我們需要根據(jù)圖片中分隔好的區(qū)域找到面積最大的一塊來點擊它。

那么我們把它拆分成以下幾個步驟:

檢測出圖中標(biāo)記的點將檢測出來的點連成線根據(jù)線分割出的區(qū)域計算各區(qū)域面積,并得到最大面積在該區(qū)域面積中選取一個坐標(biāo)點作為結(jié)果

一、檢測出圖中標(biāo)記的點

第一個問題,怎么檢測出圖片中被標(biāo)記出來的點?

這里使用哈里斯角點檢測,這里采用OpenCV中的cornerHarris()來實現(xiàn)。
參考下面兩篇文章,感興趣的話可以閱讀一下:

Harris角點檢測原理詳解圖像特征之Harris角點檢測

效果如下圖

使用java + OpenCV破解頂象面積驗證碼的示例

java" id="highlighter_936596">
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
     * 哈里斯角點檢測
     * @param img   原圖地址
     * @param img2  新圖地址
     */
    public void getHarris(String img,String img2) {
        System.load(dllPath);
        File bFile = new File(img);
        try {
            Mat mat = Imgcodecs.imread(bFile.getPath());
            // 轉(zhuǎn)灰度圖像
            Mat gray = new Mat();
            Imgproc.cvtColor(mat, gray, Imgproc.COLOR_BGR2GRAY);
            // 角點發(fā)現(xiàn)
            Mat harris = new Mat();
            Imgproc.cornerHarris(gray, harris, 2, 3, 0.04);
            // 繪制角點
            float[] floats = new float[harris.cols()];
            for (int i = 0; i < harris.rows(); i++) {
                harris.get(i, 0, floats);
                for (int j = 0; j < floats.length; j++) {
                    if (floats[j] > 0.0001) {// 越接近于角點數(shù)值越大
                        System.out.println(floats[j]);
                        Imgproc.circle(mat, new Point(j, i), 1, new Scalar(0, 255, 0));
                    }
                }
            }
            Imgcodecs.imwrite(img2, mat);
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

那標(biāo)記點的檢測完成了。

二、將檢測出來的點連成線

如何連線就比較簡單了,這里我們只需要在繪制角點的時候?qū)⒔痉秶O(shè)置大一點就好了,這里設(shè)置為5即可。

?
1
Imgproc.circle(mat, new Point(j, i), 5, new Scalar(0, 255, 0));

下面是效果圖

使用java + OpenCV破解頂象面積驗證碼的示例

連線做到這樣的效果就可以了。

三、根據(jù)線分割出的區(qū)域計算各區(qū)域面積,并得到最大面積

這里根據(jù)深度優(yōu)先搜索的原理,劃分不同區(qū)域最終選出最大的一塊面積;

深度優(yōu)先搜索大家不會的話就可以參考這篇文章:
基本算法——深度優(yōu)先搜索(DFS)和廣度優(yōu)先搜索(BFS)

這里直接搜索了所有區(qū)域。將占像素量最多的區(qū)域顯示了出來,效果如圖:

使用java + OpenCV破解頂象面積驗證碼的示例

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/**根據(jù)線分割出的區(qū)域計算各區(qū)域面積,并得到最大面積
     * @param oldimg 原圖
     * @param newimg 繪制角點后的圖
     */
     */
    public void getMatrix(String oldimg,String newimg) {
        File ofile = new File(oldimg);
        File nfile = new File(newimg);
        try {
            BufferedImage oimage = ImageIO.read(ofile);
            BufferedImage nimage = ImageIO.read(nfile);
            int matrix[][] = new int[nimage.getWidth()][nimage.getHeight()];
            int rank = 0;
            int maxRank = 0;
            int count = 0;
            int maxCount = 0;
            //將檢測并高亮部分置1,其余部分置0,得到一個代替圖的二維數(shù)組
            for (int w = 0; w < nimage.getWidth(); w++) {
                for (int h = 0; h < nimage.getHeight(); h++) {
                    int[] bgRgb = new int[3];
                    bgRgb[0] = (nimage.getRGB(w, h) & 0xff0000) >> 16;
                    bgRgb[1] = (nimage.getRGB(w, h) & 0xff00) >> 8;
                    bgRgb[2] = (nimage.getRGB(w, h) & 0xff);
                    if (!(bgRgb[0] <= 70 && bgRgb[1] >= 180 && bgRgb[2] <= 70)) {
                        matrix[w][h] = 0;
                    } else {
                        matrix[w][h] = -1;
                    }
                }
            }
            //深度優(yōu)先搜索找出最大區(qū)域
            while (true) {
                int n = 0;
                for (int i = 0; i < matrix.length; i++) {
                    for (int j = 0; j < matrix[0].length; j++) {
                        if (matrix[i][j] == 0) {
                            n++;
                            rank++;
                            count = dfs(matrix, rank);
                            if (count > maxCount) {
                                maxCount = count;
                                maxRank = rank;
                            }
                        }
                    }
                }
                if (n == 0)
                    break;
            }
            //改變最大區(qū)域顏色
            for (int j = 0; j < matrix[0].length; j++) {
                for (int i = 0; i < matrix.length; i++) {
                    if (matrix[i][j] == maxRank){
                        nimage.setRGB(i, j, new Color(0, 0, 255).getRGB());
                    }
                }
            }
            ImageIO.write(image, "png", new File(img));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 深度優(yōu)先搜索
     * @param matrix 圖信息數(shù)組
     * @param n 標(biāo)記數(shù)
     * @return
     */
    public int dfs(int matrix[][], int rank) {
        int count = 0;
        int w = -1;
        int h = -1;
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                if (matrix[i][j] == 0) {
                    w = i;
                    h = j;
                    break;
                }
            }
            if (w != -1) {
                break;
            }
        }
        Stack<JSONObject> stack = new Stack<JSONObject>();
        while (matrix[w][h] == 0 || h == stack.peek().getIntValue("h") && w == stack.peek().getIntValue("w")) {
            JSONObject json = new JSONObject();
            json.put("w", w);
            json.put("h", h);
            stack.push(json);
            matrix[w][h] = rank;
            count++;
            if (h + 1 < matrix[0].length) {
                if (matrix[w][h + 1] == 0) {
                    h = h + 1;
                    continue;
                }
            }
            if (w + 1 < matrix.length) {
                if (matrix[w + 1][h] == 0) {
                    w = w + 1;
                    continue;
                }
            }
            if (h - 1 >= 0) {
                if (matrix[w][h - 1] == 0) {
                    h = h - 1;
                    continue;
                }
            }
            if (w - 1 >= 0) {
                if (matrix[w - 1][h] == 0) {
                    w = w - 1;
                    continue;
                }
            }
            stack.pop();
            if (!stack.empty()) {
                if (h == stack.peek().getIntValue("h") && w == stack.peek().getIntValue("w")) {
                    stack.pop();
                }
            }
            if (!stack.empty()) {
                w = stack.peek().getIntValue("w");
                h = stack.peek().getIntValue("h");
            } else {
                break;
            }
        }
        return count;
    }

四、 在該區(qū)域面積中選取一個坐標(biāo)點作為結(jié)果

這里我們都已經(jīng)找到面積最大區(qū)域了,就隨意取一個點就好了

將上面代碼中的

?
1
2
3
4
5
6
7
8
//改變最大區(qū)域顏色
for (int j = 0; j < matrix[0].length; j++) {
    for (int i = 0; i < matrix.length; i++) {
        if (matrix[i][j] == maxRank){
            nimage.setRGB(i, j, new Color(0, 0, 255).getRGB());
        }
    }
}

改為下面的代碼即可

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//標(biāo)記選取到的點
boolean flag = false;
for (int j = 0; j < matrix[0].length; j++) {
    for (int i = 0; i < matrix.length; i++) {
        if (matrix[i][j] == maxRank) {
            oimage.setRGB(i, j, new Color(255, 0, 0).getRGB());
            System.out.println("w=" + i + "|h=" + j);
            flag = true;
            break;
        }
    }
    if (flag) {
        break;
    }
}

結(jié)果展示:

使用java + OpenCV破解頂象面積驗證碼的示例

本文思路參考:https://blog.csdn.net/aaronjny/article/details/110245896

到此這篇關(guān)于使用java + OpenCV破解頂象面積驗證碼的示例的文章就介紹到這了,更多相關(guān)java頂象面積驗證碼內(nèi)容請搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!

原文鏈接:https://blog.csdn.net/weixin_49701447/article/details/110627934

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚飞与亚基高清国语在线观看 | 国产梦呦精品 | 操熟美女又肥又嫩的骚屁股 | 亚州精品视频 | 国产成人无精品久久久 | 艾秋果冻麻豆老狼 | 国产一级特黄aa大片免费 | 亚洲天堂色图 | 精品一区二区三区高清免费观看 | 欧美特一级 | 寡妇一级毛片 | 国产日韩成人 | 99久久综合 | 欧美高清日韩 | 五月天网站 | 深夜在线观看 | 俄罗斯一级毛片免费播放 | 国产馆在线观看免费的 | 果冻传媒和91制片厂网站软件 | 国产精品久久久久久久久齐齐 | 金牛网155755水心论坛黄大父母 | 欧洲美女女同 | 天天综合五月天 | 先锋资源久久 | 99久久精品6在线播放 | 鬼吹灯天星术在线高清观看 | 天天操天天爽天天射 | a天堂中文在线 | h日本漫画全彩在线观看 | 国产成人精品日本亚洲网站 | 国产婷婷综合丁香亚洲欧洲 | 全黄h全肉细节文在线观看 全彩成人18h漫画 | 波多野结衣在线看 | 人妖欧美一区二区三区四区 | 国产男人搡女人免费视频 | 韩国三级年轻小的胰子完整 | 无人在线观看免费高清视频播放 | 波多野结中文字幕在线69视频 | 日本特黄一级午夜剧场毛片 | 免费一级欧美片在线观免看 | 亚洲国产第一区二区香蕉日日 |