2013-01-25 07:31:21 xiaowei_cqu 阅读数 7373

在一些国内的论文中看到尖角检测方法,感觉有点类似以前学过的“种子填充”或者“扫描线”。


算法描述

按照从上到下,从左到右的顺序扫描整个二值图像。遇到像素为白色时不做任何标记,继续扫描下一像素;遇到黑色像素,则判断周围像素是否被标记的情况来决定本像素的标记情况。可分为4种情况:

  1. 若该像素的上方和左方除了0和255外没有其它的标记,则将该像素设置一个新的标记;
  2. 若该像素上方有除了0和255外其它的标记而左方没有,则设置为和上方像素相同的标记;
  3. 若该像素左方有除了0和255外其它的标记而上方没有,则设置为和左方像素相同的标记;
  4. 若该像素的上方和左方除了0和255外都有其它的标记,如果上方和左方的标记相同,则将该像素

设置为和该标记相同的标记;如果上方和左方的标记不相同,将该像素设置为和上方像素相同的标记,然后将左方重新标记。重新标记是将该像素的左方与之连续且和它左边的像素标号一样的像素点都重新标记为和当前像素一样的标记,当遇到亮点即像素值为255或图像边界或与需要重新标记的标号不一致时重新标记结束。处理结束后扫描下一像素,扫描完一行进入下一行,遇到黑色的像素点处理方法和以上相同。所有处理结束后再对整个图像扫描一遍,统计尖角的数目,计算每个尖角所在联通区域的面积(即该区域内的像素点数)以及它们的高度。

论文中的一个示意图:



代码实现

自己写的比较笨拙的代码:

void FireDetector::CheckTaperAngle(Mat &img)
{
	int dilation_type = MORPH_RECT;
	int dilation_size=5;
	Mat element = getStructuringElement( dilation_type,
		Size( 2*dilation_size + 1, 2*dilation_size+1 ),
		Point( dilation_size, dilation_size ) );
	Mat copyImage,angGray;
	img.copyTo(copyImage);
	dilate(copyImage,copyImage,Mat());
	dilate(copyImage,copyImage,Mat());
	copyImage.copyTo(angGray);
	//imshow("dilage",img);
	int nrows=angGray.rows;
	int ncols=angGray.cols;
	
	//cvtColor(copyImage,angGray,CV_BGR2GRAY);
	
	int flag=1;
	for(int i=0;i<nrows;i++){
		uchar *pimg=copyImage.ptr<uchar>(i);
		uchar *pgray=angGray.ptr<uchar>(i);
		for(int j=0;j<ncols;j++){
			if(pimg[j]>0){
				if(i>0&&j>0){
					uchar* ppgray=angGray.ptr<uchar>(i-1);
					if(ppgray[j]==0&&pgray[j-1]==0)
						pgray[j]=flag++;
					else if(ppgray[j]>0&&pgray[j-1]==0){
						pgray[j]=ppgray[j];
					}
					else if(pgray[j-1]>0&&ppgray[j]==0){
						pgray[j]=pgray[j-1];
					}
					else if(pgray[j-1]>0&&ppgray[j]>0&&pgray[j-1]==ppgray[j]){
						pgray[j]=pgray[j-1];
					}
					else{
						ppgray[j]=flag++;
						pgray[j]=ppgray[j];
						uchar tmp=pgray[j-1];
						for(int k=j-1;k>0;k--){
							if(pgray[k]==tmp)
								pgray[k]=pgray[j];
						}
					}
				}// end if: i>0&&j>0
				else if(j>0&&i==0){
					if(pgray[j-1]>0)
						pgray[j]=pgray[j-1];
					else
						pgray[j]=flag++;
				} //end else if: j>0&&i==0
				else if (i>0&&j==0){
					uchar *ppgray =angGray.ptr<uchar>(i-1);
					if(ppgray[j]>0)
						pgray[j]=ppgray[j];
					else
						ppgray[j]=flag++;
				} //end else if: i>0&&j==0
				else{
					pgray[j]=flag++;
				}
			} // end if: pimg[j]>0
		} //end for: int j=0;j<ncols;j++
	} //end for: int i=0;i<nrows;i++
	//imshow("AngleGray",angGray);

	//标记完后画尖角的图
	Mat table = (Mat_<double>(10,3) <<  0, 0, 1 , 0.5, 0.4, 0.25, 0.5, 0.5, 0.5, 0, 1, 0, 1, 0.8, 0, 1, 0.5, 1, 1, 0, 1 , 1, 0, 0, 1, 1, 1, 1, 1, 0 );
	cvtColor(angGray,angleImg,CV_GRAY2BGR);
	int channels=angleImg.channels();
	for(int i=0;i<nrows;i++){
		uchar* pgray=angGray.ptr<uchar>(i);
		uchar* pang=angleImg.ptr<uchar>(i);
		for(int j=0,jcol=0;j<ncols,jcol<ncols*channels;j++,jcol+=channels){
			uchar flagvalue=pgray[j];
			if(flagvalue>0){
				for(int k=0;k<3;k++){
					int indexpix=(int)(flagvalue%10);
					double tmp= table.at<double>(indexpix,2-k);
					pang[jcol+k]=(uchar)tmp*255;
				} // end for: k
			}
		} //end for: j
	} //end for: i
//	cout<<flag<<endl;
//	imshow("Taper angle",angleImg);
}

实验效果

代码中“画尖角图”的部分使用了很多颜色,只是希望显示出一个尖角一种颜色的视觉效果:


原场景是这样的:


这种方法就是对像素太敏感了,一个像素的突出也会计算为尖角,实用性比较差。


参考文献

[1] 顾俊傻 赵敏 吴毅杰.早期火灾火焰尖角计算算法的研究[J].青岛大学学报,2010,25(1):24-27.


(转载请注明作者和出处:http://blog.csdn.net/xiaowei_cqu 未经允许请勿用于商业用途)



2013-01-17 21:07:38 xiaowei_cqu 阅读数 18829

学期末一直忙考试,大作业,很久没来CSDN耕耘了。。。

虽然考试都结束了,手头还是累积了不少活儿要补,不多写了,晒个小项目,之前一直做的,后来当做模式识别课程的大作业交了。

大体框架如下:

 

还是之前的火灾检测,但是在一些简单的颜色、运动检测的基础上增加了模式识别的方法。(其实并不需要这么多种方法,因为作业要求试验三种以上的方法)

因为特征比较简单——SVM、非线性SVM、决策树、随机森林都是用的颜色直方图来训练;Adaboost就是完全用的《Rapid》中的Haar特征——所以其实模式识别方法并没有实质性的提高检测率,主要的检测效果还是依据前期初期得到的。

以下是用QT实现的小Demo:

 

再晒个检测效果图:

都是比较简单的场景,所以看上去效果还行,嘿嘿~

 

(转载请注明作者和出处:http://blog.csdn.net/xiaowei_cqu 未经允许请勿用于商业用途)

 

 

 

 

2019-10-24 11:35:53 qq_43100178 阅读数 447

数据集

下载链接:https://github.com/steffensbola/furg-fire-dataset
内容:MP4的视频和对应的xml文件
问题:1.This XML was generated using OpenCv 2.4.9
2.xml文件中很多帧的图片没有坐标信息

目标:处理成VOC2007数据集格式

一,视频解帧

import cv2
import numpy as np
import os


def save_img():
    video_path = r"F:\Fire\furg_fire_dataset\mp4/"
    save_path = r"F:\Fire\furg_fire_dataset\img/"
    videos = os.listdir(video_path)
    print(len(videos),videos)
    for video_name in videos:
        file_name = video_name.split('.')[0]
        # print(file_name)
        folder_name = save_path + file_name
        # print(folder_name)
        # exit()
        os.makedirs(folder_name, exist_ok=True)
        print("="*10+'开始处理视频:%s'%video_name+"="*10)
        vc = cv2.VideoCapture(video_path + video_name)
        c = 0
        rval = vc.isOpened()

        while rval:

            rval, frame = vc.read()
            pic_path = folder_name + '/'
            if rval:
                cv2.imwrite(pic_path + str(c) + '.jpg', frame)
                cv2.waitKey(1)
                c += 1
            else:
                break
            print('='*10+'%s图片数量:%i'%(video_name,c)+'='*10)
        vc.release()
        print('save_success')
        print(folder_name)

save_img()

二,处理原始xml文件,使用库xml.etree.ElementTree和xml.dom.minidom解析我都没成功。发现里面的节点格式不对,我就换了种处理方式,把xml格式转成txt文本格式。

import os
import re
import re

path = r"F:\Fire\furg_fire_dataset\ann/"
save_path = r"F:\Fire\furg_fire_dataset\txt/"
xml_file = os.listdir(path)
for txt_file in xml_file:
    print('='*10+'开始处理:'+txt_file+'='*10)
    file = txt_file.split('.')[0]
    # print(file)
    new_file = file+'.txt'
    xml_dir = path+txt_file
    txt_dir = path+new_file
    print(xml_dir,txt_dir)
    # exit()
    os.rename(xml_dir,txt_dir)
    print('+'*10+'%s更改格式:'%txt_file+new_file+'+'*10)
    print(save_path+txt_file)
    # exit()
    pic_name = []
    box_data = {}
    index = ['0,','1','2','3','4','5','6','7','8','9']

    # with open(path+txt_file) as f:
    with open(txt_dir) as f:

        strs = f.readlines()
        # print(strs)
        count = 0
        for i in strs:
            # print(i)
            # print(i.strip())
            c = i.strip()[0]
            # print('===============',c)
            # print(type(c))
            t_f = i.strip()[-18:]
            im_file = i.strip()[-14:]
            # print(im_file)
            # print('t-f===================',t_f)
            # exit()
            if t_f == '</annotations></_>':
                box_data[count] = i.strip()
                count +=1
                # print('+++++++++++++++++++++++++++++++++++',i)
            elif im_file == '</frameNumber>':
                pic_name.append(i.strip())
                # print('===================================',i)
            else:
                print('出错%s'%i)

    # print("pic_name:",pic_name)
    # print("box_data:",box_data)

    dict = {}
    for i in range(len(pic_name)-1):
        pic = pic_name[i].split('</')
        # print(pic)
        # print(pic[0][16:])
        for j in range(len(box_data)):
            box = box_data[j].split('</_></a')
            # print(box)
            # print(box[0])
            if i == j:
                dict[pic[0][16:]] = box[0]
            # else:
            #     dict[pic[0][16:]] = 'null'


    print("pic_name:",pic_name)
    print("box_data:",box_data)
    print(dict)
    print(len(pic_name))
    print(len(box_data))


    # with open(save_path+txt_file,'w') as f:
    with open(save_path+new_file,'w') as f:
        for k in dict:
            f.write(str(k) + ' '+dict[k]+'\n')
    print('&'*15+'%s处理结束!'%txt_file+'&'*15)

三,处理视频解帧的图片,删除没有标签信息的图片

import os
import re
import glob


img_path = r"F:\Fire\furg_fire_dataset\img/"
txt_path = r"F:\Fire\furg_fire_dataset\txt/"

file_names = os.listdir(img_path)

for file_name in file_names:
    print('&'*10+'开始处理图片文件夹:'+file_name+'&'*10)

    # exit()
    img_file = []
    txt_file = []
    txt_dir = txt_path+file_name+'.txt'
    print("="*10+'处理txt文本:'+txt_dir+'='*10)

    with open(txt_dir) as f:
        strs = f.readlines()
        print('strs:',strs)
        for txt in strs:
            # print(txt)
            s = txt.strip().split(' ')
            # print(s,s[0],s[1])
            if s[1]=='</annotations></_>':
                img_file.append(s[0])
            else:
                txt_file.append(txt.strip())
        # print(txt_file)
        # print(len(txt_file),len(strs))
        print('错误图片:',img_file,len(img_file))
        with open(txt_dir,'w') as k:
            for t in txt_file:
                k.write(t+'\n')

    for im in os.listdir(os.path.join(img_path, file_name)):
        # print(im)
        # print(i)
        pic = im.split('.')[0]
        t_f = pic in img_file
        # print(t_f)

        if t_f:
            print('+'*12+'错误图片数:'+str(len(img_file))+'+'*12)
            print('+'*8+'删除图片:'+img_path +file_name+'/'+ im+'+'*8)
            os.remove(img_path+file_name+'/'+im)

四,把图片重命名并复制到空的文件夹

import os
import shutil


# 复制图片到新的文件夹
path = r"F:\Fire\furg_fire_dataset\img/"
xml_path = r"E:\xunleidownload\fire-dataset-dunnings\videos\furg-fire-dataset\Annotations/"
save_path = r"F:\Fire\furg_fire_dataset\pic/"

file_path = os.listdir(path)
print(len(file_path),file_path)

for i in file_path:
    img_files = os.listdir(path+i)
    print(i)
    for img in img_files:
        # print(img)
        src_dir = path+i+'/'+img
        dst_dir = path+i+'/'+i+img
        pic_dir = save_path+ i+img
        # print(img)
        print(src_dir)
        print(dst_dir)
        print(pic_dir)
        # exit()
        os.rename(src_dir,dst_dir)
        shutil.copyfile(dst_dir,pic_dir)

五,使用txt的标签信息,生成图片对应的xml文件

import os, sys
import glob
from PIL import Image

obj_name = 'fire'
src_img_dir = r"F:\Fire\furg_fire_dataset\img\HouseTwo"
src_txt_dir = r"F:\Fire\furg_fire_dataset\txt\HouseTwo.txt"
# src_xml_dir = r"F:\Fire\furg_fire_dataset\xml"
src_xml_dir = r"F:\Fire\furg_fire_dataset\xml"
# src_txt_dir = src_img_dir + 'F:\Fire\furg_fire_dataset\xml'
# src_xml_dir = src_img_dir

img_Lists = glob.glob(src_img_dir + '/*.jpg')
print(img_Lists)
img_basenames = []  # e.g. 100.jpg
for item in img_Lists:
    img_basenames.append(os.path.basename(item))

img_names = []  # e.g. 100
for item in img_basenames:
    temp1, temp2 = os.path.splitext(item)
    img_names.append(temp1)

for img in img_names:
    im = Image.open((src_img_dir + '/' + img + '.jpg'))
    print('img_name:',img)
    img_label = img.split('seTwo')[1]
    print('img_label:',img_label)
    # exit()
    width, height = im.size

    # open the crospronding txt file
    gt = open(src_txt_dir).read().splitlines()  # int x,int y,int width,int height  x,y是左上角
    print('boxes:',gt)
    # exit()
    # gt = open(src_txt_dir + '/gt_' + img + '.txt').read().splitlines()

    # write in xml file
    # os.mknod(src_xml_dir + '/' + img + '.xml')
    xml_file = open((src_xml_dir + '/' + img + '.xml'), 'w')
    xml_file.write('<annotation>\n')
    xml_file.write('    <folder>VOC2007</folder>\n')
    xml_file.write('    <filename>' + str(img) + '.jpg' + '</filename>\n')
    xml_file.write('    <size>\n')
    xml_file.write('        <width>' + str(width) + '</width>\n')
    xml_file.write('        <height>' + str(height) + '</height>\n')
    xml_file.write('        <depth>3</depth>\n')
    xml_file.write('    </size>\n')

    # write the region of image on xml file
    for img_each_label in gt:
        spt = img_each_label.split(' ')  # 这里如果txt里面是以逗号‘,’隔开的,那么就改为spt = img_each_label.split(',')。
        # print("========",spt)
        if spt[0] == img_label:
        # print(spt[0])
        # print(spt[-1])
        # print(int(float(int(spt[1])+int(spt[3]))))
        # print(int(spt[2])+int(spt[4]))
        # exit()
            xml_file.write('    <object>\n')
            # xml_file.write('        <name>' + str(spt[-5])+' '+str(spt[-6]) + '</name>\n')
            xml_file.write('        <name>' + obj_name + '</name>\n')
            xml_file.write('        <pose>Unspecified</pose>\n')
            xml_file.write('        <truncated>0</truncated>\n')
            xml_file.write('        <difficult>0</difficult>\n')
            xml_file.write('        <bndbox>\n')
            xml_file.write('            <xmin>' + str(int(float(spt[1]))) + '</xmin>\n')
            xml_file.write('            <ymin>' + str(int(float(spt[2]))) + '</ymin>\n')
            xml_file.write('            <xmax>' + str(int(float(int(spt[1])+int(spt[3])))) + '</xmax>\n')
            xml_file.write('            <ymax>' + str(int(float(int(spt[2])+int(spt[4])))) + '</ymax>\n')
            xml_file.write('        </bndbox>\n')
            xml_file.write('    </object>\n')

    xml_file.write('</annotation>')

六,VOC2007格式的JPEGImages和Annotations已备齐。还缺ImageSets\Main下的训练测试文本。

import os
import random
from glob import glob
import shutil

saved_path = r'F:\Fire\smoke\MP4\smoke_detect-PascalVOC-export\VOC2007/'
# saved_path = r"E:\xunleidownload\VOCdevkit\VOC2007/"
# trainval_percent = 0.66
trainval_percent = 0.8
# train_percent = 0.8
#
train_percent = 0.8
xmlfilepath = saved_path + 'Annotations/'
txtsavepath = saved_path + 'ImageSets/Main'
total_xml = os.listdir(xmlfilepath)

num=len(total_xml)
list=range(num)
tv=int(num*trainval_percent)
tr=int(tv*train_percent)
trainval= random.sample(list,tv)
train=random.sample(trainval,tr)

ftrainval = open(saved_path + 'ImageSets/Main/trainval.txt', 'w')
ftest = open(saved_path + 'ImageSets/Main/test.txt', 'w')
ftrain = open(saved_path + 'ImageSets/Main/train.txt', 'w')
fval = open(saved_path + 'ImageSets/Main/val.txt', 'w')

for i  in list:
    name=total_xml[i][:-4]+'\n'
    if i in trainval:
        ftrainval.write(name)
        if i in train:
             ftrain.write(name)
        else:
             fval.write(name)
    else:
         ftest.write(name)

ftrainval.close()
ftrain.close()
fval.close()
ftest .close()
2015-10-09 13:51:41 u012211748 阅读数 486

1.《手背血管预处理--利用PIL进行数字图像的综合处理》

http://www.cnblogs.com/chenxofhit/archive/2011/05/20/2052182.html

2.《森林火灾检测

http://blog.csdn.net/xiaowei_cqu/article/details/7522467

http://blog.csdn.net/xiaowei_cqu/article/details/7523683

3.《笔迹鉴别》

笔迹鉴别(1) —— 实现步骤概述
笔迹鉴别(2) —— 纹理制作
笔迹鉴别(3) —— Gabor变换(1)
笔迹鉴别(4) —— Gabor变换(2)
笔迹鉴别(5) —— 笔迹判别

http://www.cnblogs.com/zhenyulu/category/47600.html

4.《用 gabor 和 MultiBoost 做图像识别

http://bbs.chinaunix.net/thread-1487582-1-1.html

5.《视频清晰度、色偏以及亮度异常检测

http://blog.csdn.net/kklots/article/details/12720359

6.《如何用摄像头来测距(opencv)


2016-05-07 09:47:00 weixin_30786617 阅读数 15

学期末一直忙考试,大作业,很久没来CSDN耕耘了。。。

虽然考试都结束了,手头还是累积了不少活儿要补,不多写了,晒个小项目,之前一直做的,后来当做模式识别课程的大作业交了。

大体框架如下:


还是之前的火灾检测,但是在一些简单的颜色、运动检测的基础上增加了模式识别的方法。(其实并不需要这么多种方法,因为作业要求试验三种以上的方法)

因为特征比较简单——SVM、非线性SVM、决策树、随机森林都是用的颜色直方图来训练;Adaboost就是完全用的《Rapid》中的Haar特征——所以其实模式识别方法并没有实质性的提高检测率,主要的检测效果还是依据前期初期得到的。

以下是用QT实现的小Demo:



再晒个检测效果图:


都是比较简单的场景,所以看上去效果还行,嘿嘿~

(转载请注明作者和出处:http://blog.csdn.net/xiaowei_cqu 未经允许请勿用于商业用途)

转载于:https://www.cnblogs.com/alan666/p/8312339.html

没有更多推荐了,返回首页