中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在java中利用OpenCV破解頂象面積驗證碼

發布時間:2021-02-04 16:15:22 來源:億速云 閱讀:224 作者:Leah 欄目:開發技術

本篇文章為大家展示了怎么在java中利用OpenCV破解頂象面積驗證碼,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

一、檢測出圖中標記的點

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

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

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

/**
	 * 哈里斯角點檢測
	 * @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());
			// 轉灰度圖像
			Mat gray = new Mat();
			Imgproc.cvtColor(mat, gray, Imgproc.COLOR_BGR2GRAY);
			// 角點發現
			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) {// 越接近于角點數值越大
						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();
		}
	}

那標記點的檢測完成了。

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

如何連線就比較簡單了,這里我們只需要在繪制角點的時候將浸染范圍設置大一點就好了,這里設置為5即可。

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

三、根據線分割出的區域計算各區域面積,并得到最大面積

這里根據深度優先搜索的原理,劃分不同區域最終選出最大的一塊面積;

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

/**根據線分割出的區域計算各區域面積,并得到最大面積
	 * @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,得到一個代替圖的二維數組
			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;
					}
				}
			}
			//深度優先搜索找出最大區域
			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;
			}
			//改變最大區域顏色
			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();
		}
	}
	/**
	 * 深度優先搜索
	 * @param matrix 圖信息數組
	 * @param n 標記數
	 * @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;
	}

四、 在該區域面積中選取一個坐標點作為結果

這里我們都已經找到面積最大區域了,就隨意取一個點就好了

將上面代碼中的

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

改為下面的代碼即可

//標記選取到的點
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;
	}
}

上述內容就是怎么在java中利用OpenCV破解頂象面積驗證碼,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

中山市| 苍山县| 伊宁县| 察雅县| 舒城县| 漯河市| 含山县| 微山县| 颍上县| 黄浦区| 镶黄旗| 乌海市| 闻喜县| 北海市| 枞阳县| 延川县| 渑池县| 会泽县| 新昌县| 裕民县| 集贤县| 丽江市| 徐汇区| 永顺县| 阿坝县| 呼图壁县| 岱山县| 周口市| 恩平市| 金阳县| 康马县| 陆丰市| 建瓯市| 武功县| 济阳县| 巴彦淖尔市| 界首市| 大荔县| 瑞安市| 崇信县| 宁化县|