Tôi có nhiều hình ảnh của sách năm với chân dung người và tôi đang cố gắng xây dựng một algorytm sẽ phát hiện những bức chân dung đó. Ít nhất, để phát hiện đúng chân dung hình chữ nhật. Example 1Example 2Phát hiện chân dung hình chữ nhật của những người trên hình ảnh với OpenCV
Tôi đang cố gắng để điều tra ba hướng:
- nhận diện khuôn mặt
- tối phát hiện hình chữ nhật (Kể từ bức chân dung là hình dạng thường sẫm trên nền sáng)
- dân tên khai thác từ OCR'ed văn bản
Bằng cách kết hợp các kết quả của ba thuật toán ở trên, tôi hy vọng sẽ nhận được một số phương pháp, sẽ áp dụng được cho nhiều trang niên giám khác nhau.
Tôi sẽ rất cảm kích vì bất kỳ trợ giúp nào cho việc phát hiện hình chữ nhật. tôi bắt đầu với Java và OpenCV 3.
Dưới đây là mã của tôi nộp đơn xin an image:
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat source = Imgcodecs.imread("Path/to/image", Imgcodecs.CV_LOAD_IMAGE_ANYCOLOR);
Mat destination = new Mat(source.rows(), source.cols(), source.type());
Imgproc.cvtColor(source, destination, Imgproc.COLOR_RGB2GRAY);
Imgproc.GaussianBlur(destination, destination, new Size(5, 5), 0, 0, Core.BORDER_DEFAULT);
int threshold = 100;
Imgproc.Canny(destination, destination, 50, 100);
Imgproc.Canny(destination, destination, threshold, threshold*3);
Tại thời điểm này, tôi có kết quả như vậy:
Cố gắng tìm đường nét từ mép ở trên:
List<MatOfPoint> contourDetections = new ArrayList<>();
Mat hierarchy = new Mat();
// Find contours
Imgproc.findContours(destination, contourDetections, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
// Draw contours
Imgproc.drawContours(source, contours, -1, new Scalar(255,0,0), 2);
Nhưng không chắc chắn cách trích xuất hình chữ nhật từ các đường viền đó vì nhiều dòng chưa hoàn thành.
Bắt trở lại cạnh và cố gắng tìm dọc và ngang dòng sử dụng HoughLinesP:
Mat lines = new Mat();
int thre = 50;
int minLineSize = 250;
int lineGap = 80;
int ignoreLinesShorter = 300;
Imgproc.HoughLinesP(destination, lines, 1, Math.PI/180, thre, minLineSize, lineGap);
for(int c = 0; c < lines.rows(); c++) {
double[] vec = lines.get(c, 0);
double x1 = vec[0],
y1 = vec[1],
x2 = vec[2],
y2 = vec[3];
// Filtering only verticat and horizontal lines
if(x1 == x2 || y1 == y2) {
// Filtering out short lines
if(Math.abs(x1 - x2) > ignoreLinesShorter || Math.abs(y1 - y2) > ignoreLinesShorter) {
Point start = new Point(x1, y1);
Point end = new Point(x2, y2);
// Draw line
Imgproc.line(source, start, end, new Scalar(0,0,255), 2);
}
}
}
Kết quả:
Giống như với đường nét, tôi vẫn không nhìn thấy hình chữ nhật đúng khi cho rằng Tôi có thể phát hiện. Bạn có thể giúp tôi với một hướng đúng không? Có thể có một cách dễ dàng hơn để thực hiện tác vụ này?
Các đường nét chưa đầy đủ vì các cạnh chưa đầy đủ. Bạn đã thử các giá trị ngưỡng thấp hơn trong Canny chưa? Ngoài ra, bạn có thể lọc các đường viền nhỏ hơn theo kích thước bằng 'contourArea'. –
Làm thế nào về * tăng * ngưỡng của đường viền và sau đó mở rộng tất cả các đường thẳng đứng và nằm ngang? –