图标点选验证码是一种防止自动化攻击的手段,要求用户点击指定的图标进行验证。本文介绍如何使用Swift结合ONNX模型和Siamese神经网络来实现图标点选验证码的识别和分割。
一、技术背景
图标点选验证码的破解分为两部分:图标分割和相似度对比。图标分割用于检测并裁剪出验证码图片中的各个图标;相似度对比则用于确定这些图标是否与指定的目标图标相匹配。
二、图标分割
1. 图像处理
首先,加载并处理图像。为了适应模型的输入要求,需要对图像进行缩放和填充。
swift
import UIKit
func paddedResize(image: UIImage, newWidth: CGFloat, newHeight: CGFloat) -> UIImage {
let oldWidth = image.size.width
let oldHeight = image.size.height
let scale = min(newWidth / oldWidth, newHeight / oldHeight)
let scaledWidth = oldWidth * scale
let scaledHeight = oldHeight * scale
let renderer = UIGraphicsImageRenderer(size: CGSize(width: newWidth, height: newHeight))
let newImage = renderer.image { (context) in
let xOffset = (newWidth - scaledWidth) / 2
let yOffset = (newHeight - scaledHeight) / 2
image.draw(in: CGRect(x: xOffset, y: yOffset, width: scaledWidth, height: scaledHeight))
}
return newImage
}
let image = UIImage(named: "path/to/image.jpg")!
let resizedImage = paddedResize(image: image, newWidth: 640, newHeight: 640)
2. ONNX模型推理
加载ONNX模型并进行目标检测。
swift
import CoreML
func detectObjects(image: UIImage) -> [CGRect] {
guard let model = try? VNCoreMLModel(for: IconDetection().model) else {
fatalError("Failed to load model")
}
let request = VNCoreMLRequest(model: model) { request, error in
// Handle results
}
let handler = VNImageRequestHandler(cgImage: image.cgImage!, options: [:])
try? handler.perform([request])
return []
}
let boxes = detectObjects(image: resizedImage)
3. 画框与裁剪
根据检测结果画出边框并裁剪图标。
swift
func drawRectangle(image: UIImage, box: CGRect) -> UIImage {
let renderer = UIGraphicsImageRenderer(size: image.size)
let newImage = renderer.image { context in
image.draw(at: CGPoint.zero)
UIColor.red.setStroke()
let rect = CGRect(x: box.origin.x, y: box.origin.y, width: box.width, height: box.height)
context.stroke(rect, width: 2)
}
return newImage
}
func cropImage(image: UIImage, box: CGRect) -> UIImage? {
guard let cgImage = image.cgImage?.cropping(to: box) else { return nil }
return UIImage(cgImage: cgImage)
}
for box in boxes {
if let croppedImage = cropImage(image: image, box: box) {
// Save croppedImage
}
}
三、相似度对比
1. Siamese神经网络
使用Siamese网络进行相似度对比。
swift
import CoreML
func preprocessImage(image: UIImage) -> CVPixelBuffer? {
let resizedImage = image.resized(to: CGSize(width: 60, height: 60))
return resizedImage.pixelBuffer()
}
func getSimilarity(model: VNCoreMLModel, img1: UIImage, img2: UIImage) -> Float? {
guard let input1 = preprocessImage(image: img1),
let input2 = preprocessImage(image: img2) else { return nil }
let request = VNCoreMLRequest(model: model) { request, error in
// Handle results
}
let handler1 = VNImageRequestHandler(cvPixelBuffer: input1, options: [:])
let handler2 = VNImageRequestHandler(cvPixelBuffer: input2, options: [:])
try? handler1.perform([request])
try? handler2.perform([request])
return nil // Return similarity result
}
let similarity = getSimilarity(model: model, img1: croppedImage, img2: targetImage)
四、测试与结果
进行模型测试并展示结果。
swift
func testModel(imagePath: String, targetImagePath: String) {
guard let image = UIImage(named: imagePath),
let targetImage = UIImage(named: targetImagePath) else { return }
let resizedImage = paddedResize(image: image, newWidth: 640, newHeight: 640)
let boxes = detectObjects(image: resizedImage)
for (index, box) in boxes.enumerated() {
if let croppedImage = cropImage(image: image, box: box) {
// Save croppedImage
let similarity = getSimilarity(model: model, img1: croppedImage, img2: targetImage)
print("Similarity for image \(index): \(similarity ?? 0)")
}
}
}
testModel(imagePath: "path/to/image.jpg", targetImagePath: "path/to/target_image.jpg")