欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用java + OpenCV破解頂象面積驗(yàn)證碼的示例

 更新時(shí)間:2021年02月03日 09:57:21   作者:香芋味的貓  
這篇文章主要介紹了使用java + OpenCV破解頂象面積驗(yàn)證碼的示例,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

前言

在這里插入圖片描述

我們又來(lái)破解驗(yàn)證碼啦,今天上場(chǎng)的是–頂象面積驗(yàn)證碼

在這里插入圖片描述

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

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

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

一、檢測(cè)出圖中標(biāo)記的點(diǎn)

第一個(gè)問(wèn)題,怎么檢測(cè)出圖片中被標(biāo)記出來(lái)的點(diǎn)?

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

Harris角點(diǎn)檢測(cè)原理詳解圖像特征之Harris角點(diǎn)檢測(cè)

效果如下圖

在這里插入圖片描述

/**
	 * 哈里斯角點(diǎn)檢測(cè)
	 * @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);
			// 角點(diǎn)發(fā)現(xiàn)
			Mat harris = new Mat();
			Imgproc.cornerHarris(gray, harris, 2, 3, 0.04);
			// 繪制角點(diǎn)
			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) {// 越接近于角點(diǎn)數(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)記點(diǎn)的檢測(cè)完成了。

二、將檢測(cè)出來(lái)的點(diǎn)連成線

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

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

下面是效果圖

在這里插入圖片描述

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

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

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

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

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

在這里插入圖片描述

/**根據(jù)線分割出的區(qū)域計(jì)算各區(qū)域面積,并得到最大面積
	 * @param oldimg 原圖
	 * @param newimg 繪制角點(diǎn)后的圖
	 */
	 */
	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;
			//將檢測(cè)并高亮部分置1,其余部分置0,得到一個(gè)代替圖的二維數(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ū)域面積中選取一個(gè)坐標(biāo)點(diǎn)作為結(jié)果

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

將上面代碼中的

//改變最大區(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());
		}
	}
}

改為下面的代碼即可

//標(biāo)記選取到的點(diǎn)
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é)果展示:

在這里插入圖片描述

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

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

相關(guān)文章

  • Java常用工具類匯總 附示例代碼

    Java常用工具類匯總 附示例代碼

    這篇文章主要介紹了Java常用工具類,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著我來(lái)一起學(xué)習(xí)學(xué)習(xí)吧,希望能給你帶來(lái)幫助
    2021-06-06
  • java解析xml的4種方式的優(yōu)缺點(diǎn)對(duì)比及實(shí)現(xiàn)詳解

    java解析xml的4種方式的優(yōu)缺點(diǎn)對(duì)比及實(shí)現(xiàn)詳解

    這篇文章主要介紹了java解析xml的4種方式的優(yōu)缺點(diǎn)對(duì)比及實(shí)現(xiàn)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • Java網(wǎng)絡(luò)編程TCP實(shí)現(xiàn)文件上傳功能

    Java網(wǎng)絡(luò)編程TCP實(shí)現(xiàn)文件上傳功能

    這篇文章主要為大家詳細(xì)介紹了Java網(wǎng)絡(luò)編程TCP實(shí)現(xiàn)文件上傳功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 淺談mybatis如何半自動(dòng)化解耦(推薦)

    淺談mybatis如何半自動(dòng)化解耦(推薦)

    這篇文章主要介紹了淺談mybatis如何半自動(dòng)化解耦,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • 淺談Java中spring 線程異步執(zhí)行

    淺談Java中spring 線程異步執(zhí)行

    這篇文章主要介紹了淺談spring 線程異步執(zhí)行,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 理解zookeeper選舉機(jī)制

    理解zookeeper選舉機(jī)制

    本文主要介紹了zookeeper選舉機(jī)制的相關(guān)知識(shí),具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-02-02
  • 淺析Java中接口和抽象類的七大區(qū)別

    淺析Java中接口和抽象類的七大區(qū)別

    Java 是一門面向?qū)ο蟮木幊陶Z(yǔ)言,面向?qū)ο蟮木幊陶Z(yǔ)言有四大特征:抽象、封裝、繼承和多態(tài)。本文介紹的接口和抽象類就是面向?qū)ο缶幊讨小俺橄蟆钡木唧w實(shí)現(xiàn)。本文也將為大家詳細(xì)講一下二者的區(qū)別,需要的可以參考一下
    2021-12-12
  • Maven pom.xml 添加本地jar包依賴以及打包方法

    Maven pom.xml 添加本地jar包依賴以及打包方法

    這篇文章主要介紹了Maven pom.xml 添加本地jar包依賴以及打包方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Google?Kaptcha驗(yàn)證碼生成的使用實(shí)例說(shuō)明

    Google?Kaptcha驗(yàn)證碼生成的使用實(shí)例說(shuō)明

    這篇文章主要為大家介紹了Google?Kaptcha驗(yàn)證碼的使用實(shí)例說(shuō)明,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • Java使用線程池執(zhí)行定時(shí)任務(wù)

    Java使用線程池執(zhí)行定時(shí)任務(wù)

    本文介紹了Java使用線程池執(zhí)行定時(shí)任務(wù),其中ScheduledThreadPool和SingleThreadScheduledExecutor都是可以執(zhí)行定時(shí)任務(wù)的,但是具體怎么執(zhí)行,下面我們一起進(jìn)入文章了解具體詳情吧
    2022-05-05

最新評(píng)論