Saya mencoba mendeteksi jumlah pipa dalam gambar ini. Untuk ini, saya menggunakan deteksi berbasis OpenCV dan Python. Berdasarkan, pada jawaban yang ada untuk pertanyaan serupa, saya dapat menemukan langkah-langkah berikut
- Buka gambar
- Saring
- Terapkan Deteksi Tepi
- Gunakan Kontur
- Periksa hitungannya
Jumlah total pipa adalah ~ 909 ketika kami menghitung secara manual, beri atau ambil 4.
Setelah menerapkan filter
import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread('images/input-rectpipe-1.jpg')
blur_hor = cv2.filter2D(img[:, :, 0], cv2.CV_32F, kernel=np.ones((11,1,1), np.float32)/11.0, borderType=cv2.BORDER_CONSTANT)
blur_vert = cv2.filter2D(img[:, :, 0], cv2.CV_32F, kernel=np.ones((1,11,1), np.float32)/11.0, borderType=cv2.BORDER_CONSTANT)
mask = ((img[:,:,0]>blur_hor*1.2) | (img[:,:,0]>blur_vert*1.2)).astype(np.uint8)*255
Saya mendapatkan gambar bertopeng ini
Ini terlihat cukup akurat dalam hal jumlah persegi panjang yang terlihat itu menunjukkan. Namun, ketika saya mencoba mengambil hitungan dan memplot kotak pembatas di atas gambar, ia mengambil banyak wilayah yang tidak diinginkan juga. Untuk lingkaran, HoughCircles memiliki cara untuk menentukan radius maks dan min. Apakah ada yang serupa untuk persegi panjang yang dapat meningkatkan akurasi. Juga, saya terbuka untuk saran untuk pendekatan alternatif untuk masalah ini.
ret,thresh = cv2.threshold(mask,127,255,0)
contours,hierarchy = cv2.findContours(thresh, 1, 2)
count = 0
for i in range(len(contours)):
count = count+1
x,y,w,h = cv2.boundingRect(contours[i])
rect = cv2.minAreaRect(contours[i])
area = cv2.contourArea(contours[i])
box = cv2.boxPoints(rect)
ratio = w/h
M = cv2.moments(contours[i])
if M["m00"] == 0.0:
cX = int(M["m10"] / 1 )
cY = int(M["m01"] / 1 )
if M["m00"] != 0.0:
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
if (area > 50 and area < 220 and hierarchy[0][i][2] < 0 and (ratio > .5 and ratio < 2)):
#cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)
cv2.circle(img, (cX, cY), 1, (255, 255, 255), -1)
count = count + 1
print(count)
cv2.imshow("m",mask)
cv2.imshow("f",img)
cv2.waitKey(0)
PEMBARUAN Berdasarkan jawaban kedua saya telah mengonversi kode c ++ ke kode python dan mendapatkan hasil yang lebih dekat tetapi masih kehilangan beberapa persegi panjang yang jelas.
Jawaban:
Tentu saja Anda dapat memfilternya berdasarkan area mereka. Saya mengambil gambar biner Anda dan melanjutkan pekerjaan seperti di bawah ini:
1- Lakukan pengulangan pada semua kontur yang Anda temukan dari findContour
2- Dalam pemeriksaan loop apakah setiap kontur, apakah kontur internal atau tidak
3- Dari kontur internal, periksa area mereka dan jika area tersebut dalam kisaran yang dapat diterima, periksa rasio lebar / tinggi masing-masing kontur dan akhirnya jika itu baik, hitung kontur itu sebagai pipa.
Saya melakukan metode di atas pada gambar biner Anda, dan menemukan 794 pipa :
(Beberapa kotak hilang, Anda harus mengubah parameter detektor tepi untuk mendapatkan lebih banyak kotak yang dapat dipisahkan dalam gambar.)
dan inilah kodenya (Ini c ++ tetapi mudah dikonversi menjadi python):
sumber
Ada banyak metode untuk mengatasi masalah ini tetapi saya ragu akan ada satu metode tanpa semacam tindakan ad-hod. Berikut adalah upaya lain untuk masalah ini.
Alih-alih menggunakan informasi tepi, saya sarankan filter mirip LBP (pola biner lokal) yang membandingkan piksel sekitarnya dengan nilai tengah. Jika persentase tertentu dari piksel di sekitarnya lebih besar dari piksel tengah, piksel tengah akan berlabel 255. jika kondisinya tidak terpenuhi, maka piksel tengah akan diberi label 0.
Metode berbasis intensitas ini dijalankan dengan asumsi bahwa pusat pipa selalu lebih gelap daripada tepi pipa. Karena membandingkan intensitas, itu harus bekerja dengan baik selama beberapa kontras tetap ada.
Melalui proses ini, Anda akan mendapatkan gambar dengan gumpalan biner untuk setiap pipa dan beberapa suara. Anda harus menghapusnya dengan kondisi yang sudah diketahui sebelumnya seperti, ukuran, bentuk, fill_ratio, warna, dll. Kondisi ini dapat ditemukan dalam kode yang diberikan.
Hasil dari pemrosesan seperti LBP
Setelah dibersihkan dengan proses morfologis
Hasil akhir dengan kotak merah menunjukkan semua kandidat gumpalan dan segmen kuning menunjukkan gumpalan yang melewati semua kondisi yang kita tetapkan. Ada beberapa alarm palsu di bawah dan di atas bundel pipa tetapi mereka dapat dihilangkan dengan beberapa syarat batas.
Total pipa ditemukan: 943
sumber