与python-openCv匹配的简单模板

时间:2015-11-25 15:03:40

标签: python opencv image-processing template-matching

我试图检测一些简单的红色图案'在图像中。这是我遵循的算法: 1)过滤掉所有其他颜色而不是红色'并创造一个黑色和白色的图像。我使用了&#c; cvtColor'通过适当的掩蔽然后我应用了GaussianBlur'减少噪音。到目前为止,一切都很好。

2)我使用了函数' matchTemplate'如下检测箭头'在图像中的模板。

问题:当'箭头'模板在照片中,它被正确检测到。 但是当它不在照片中时,算法会检测出其他一些错误的形状。 有人可以修改代码,这样当箭头模板不在图片中时,没有任何东西被检测到。 这是我的代码:

    template = cv2.imread(address,0)
    w, h = template.shape[::-1]
    res = cv2.matchTemplate(self.image['blured'], template, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    top_left = max_loc
    bottom_right = (top_left[0] + w, top_left[1] + h)
    cv2.rectangle(self.image['blured'],top_left, bottom_right, 255, 2)
    cv2.rectangle(self.image['normal'], top_left, bottom_right, 255,2)

以下是结果: Correctly detected

enter image description here

错误的检测: circle is detected as arrow

enter image description here

我的模板图片,我从主照片中精确裁剪:

enter image description here

任何人都可以发现我的错误?我是图像处理的新手。提前致谢。

2 个答案:

答案 0 :(得分:1)

您必须查看max_val并为其设置一个阈值。

假设图片包含箭头时max_valx1,而当图片不包含箭头时x2x1 > x2,则threshold=(x1+x2)/2应为max_val > threshold。作为第一个暂定值,您可以选择image,然后选择w,然后在图像中找到模式,否则找不到模式。

原因是matchTemplate

  

幻灯片浏览h,比较大小为templ的重叠补丁   \ times result使用指定的方法对res进行存储并存储    SELECT * FROM groups; +----+--------+-------------+-------------------+-------------------------+ | id | Name | ReferenceID | IsReferenceRecord | GroupHasReferenceRecord | +----+--------+-------------+-------------------+-------------------------+ | 1 | Black | 1 | NULL | NULL | | 2 | Red | 1 | NULL | NULL | | 3 | Blue | 1 | Y | NULL | | 4 | Green | 2 | NULL | NULL | | 5 | Orange | 2 | NULL | NULL | | 6 | Yellow | 2 | Y | NULL | | 7 | Pink | 3 | NULL | NULL | | 8 | White | 3 | NULL | NULL | +----+--------+-------------+-------------------+-------------------------+ 中的比较结果。

因此,无论图片中是否存在箭头,您的图片org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type java.util.Date to type org.joda.time.DateTime at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:313) ~[spring-core-4.2.3.RELEASE.jar:4.2.3.RELEASE] at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:195) ~[spring-core-4.2.3.RELEASE.jar:4.2.3.RELEASE] at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:176) ~[spring-core-4.2.3.RELEASE.jar:4.2.3.RELEASE] at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readValue(MappingMongoConverter.java:1179) ~[spring-data-mongodb-1.8.1.RELEASE.jar:na] at org.springframework.data.mongodb.core.convert.MappingMongoConverter.access$200(MappingMongoConverter.java:78) ~[spring-data-mongodb-1.8.1.RELEASE.jar:na] at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1133) ~[spring-data-mongodb-1.8.1.RELEASE.jar:na] at org.springframework.data.mongodb.core.convert.MappingMongoConverter.getValueInternal(MappingMongoConverter.java:869) ~[spring-data-mongodb-1.8.1.RELEASE.jar:na] at org.springframework.data.mongodb.core.convert.MappingMongoConverter$1.doWithPersistentProperty(MappingMongoConverter.java:282) ~[spring-data-mongodb-1.8.1.RELEASE.jar:na] at org.springframework.data.mongodb.core.convert.MappingMongoConverter$1.doWithPersistentProperty(MappingMongoConverter.java:270) ~[spring-data-mongodb-1.8.1.RELEASE.jar:na] at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:309) ~[spring-data-commons-1.11.1.RELEASE.jar:na] at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:270) ~[spring-data-mongodb-1.8.1.RELEASE.jar:na] at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:231) ~[spring-data-mongodb-1.8.1.RELEASE.jar:na] at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:191) ~[spring-data-mongodb-1.8.1.RELEASE.jar:na] at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:187) ~[spring-data-mongodb-1.8.1.RELEASE.jar:na] at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:78) ~[spring-data-mongodb-1.8.1.RELEASE.jar:na] at org.springframework.data.mongodb.core.MongoTemplate$ReadDbObjectCallback.doWith(MongoTemplate.java:2215) ~[spring-data-mongodb-1.8.1.RELEASE.jar:na] at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:1891) ~[spring-data-mongodb-1.8.1.RELEASE.jar:na] at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1714) ~[spring-data-mongodb-1.8.1.RELEASE.jar:na] at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1697) ~[spring-data-mongodb-1.8.1.RELEASE.jar:na] at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:602) ~[spring-data-mongodb-1.8.1.RELEASE.jar:na] 始终都会有最大值。

答案 1 :(得分:1)

非常感谢Alessandro Jacopson。 我修改了代码并以这种方式解决了问题。这几乎是你提出的建议:

        template = cv2.imread(address,0)
        w, h = template.shape[::-1]
        res = cv2.matchTemplate(self.image['blured'], template,cv2.TM_CCOEFF_NORMED)
        threshold = 0.9
        loc = np.where( res >= threshold)
        for pt in zip(*loc[::-1]):
           cv2.rectangle(self.image['blured'], pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
           cv2.rectangle(self.image['normal'], pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)

通过这种方式,检测到模式非常准确。 新问题:对方向和旋转敏感。如果旋转,它不会检测到图案。例如,大约45度。 我可以设置任何参数,并使算法找到模式,虽然它是旋转或缩放的?