我正在尝试使用机器学习进行火灾探测。我的特征是平均RGB,方差RGB和Hu矩。
所以我现在要做的是首先分割基于图像的 on this paper
根据论文我使用规则
r > g && g > b
r > 190 && g > 100 && b < 140
这是我对负片和正片进行颜色分割的结果
右边的图片现在在
vector<Mat> processedImage
之后,我通过将每张图片转换为灰度并使其模糊来获得每张图片的细节。
cvtColor(processedImage[x], gray_image, CV_BGR2GRAY);
blur(gray_image, gray_image, Size(3, 3));
Canny(gray_image, canny_output, thresh, thresh * 2, 3);
findContours(canny_output, contours, hierarchy, CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
cv::Moments mom = cv::moments(contours[0]);
cv::HuMoments(mom, hu); // now in hu are your 7 Hu-Moments
现在我被困住了,因为负像是如此分散,所以我不确定我的图像是否可以获取有用的时间。
关于胡矩提取,我是否走上正确的轨道?在提取hu瞬间之前,我会在测试颜色分割的地方做同样的事情吗?
最佳答案
我认为您应该遵循以下步骤(Python中的代码):
1.通过遍历原始图像来创建二进制图像。如果一个像素被识别为火,则将变为白色,否则变为黑色(使用BRG或RGB时要小心。OpenCV会读取BRG中的图像,因此需要先进行转换):
rows,cols = im2.shape[:2]
for i in xrange(rows):
for j in xrange(cols):
if im2[i,j,0]>im2[i,j,1] and im2[i,j,1]>im2[i,j,2] and im2[i,j,0]>190 and im2[i,j,1] > 100 and im2[i,j,2] <140:
im2[i,j,:]=255
else:
im2[i,j,:]=0
结果:
2.使用形态学运算符和模糊处理以减少噪声/小轮廓。
# Convert to greyscale-monochromatic
gray = cv2.cvtColor(im2,cv2.COLOR_RGB2GRAY)
#Apply Gaussian Blur
blur= cv2.GaussianBlur(gray,(7,7),0)
# Threshold again since after gaussian blur the image is no longer binary
(thresh, bw_image) = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY| cv2.THRESH_OTSU)
# Difine Kernel Size and apply erosion filter
element = cv2.getStructuringElement(cv2.MORPH_RECT,(7,7))
dilated=cv2.dilate(bw_image,element)
eroded=cv2.erode(dilated,element)
3.之后,您可以使用cv2.RETR_EXTERNAL标志检测轮廓,因此可以忽略所有内部轮廓(仅对着火区域的外部轮廓感兴趣)。此外,您只能保留大于例如的轮廓。 500px或如果您知道只有一个“火”,则选择较大的一个。
g, contours,hierarchy = cv2.findContours(eroded,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
contours_retain=[]
for cnt in contours:
if cv2.contourArea(cnt)>500:
contours_retain.append(cnt)
cv2.drawContours(im_cp,contours_retain,-1,(255,0,255),3)
这是火灾区域:
4,最后计算你的胡时刻
for cnt in contours_retain:
print cv2.HuMoments(cv2.moments(cnt)).flatten()
我希望这有帮助!对不起,我对C++不熟悉!