【python脚本】在图像中标注目标,并保存结果

说明
【功能】在图像中用鼠标拖一个矩形,并将这个矩形框的像素坐标保存到文件
【输入参数】

  • image_path: 图像的根路径
  • output_file: 输出文件路径,如 /xx/xx/res.txt
import argparse
import cv2
import os

class RectangularSelection:
    def __init__(self, image_path, output_file):
        self.image_path = image_path
        self.output_file = output_file

    def run(self):
        # 1. check and prepare
        if not os.path.exists(self.image_path):
            print('\33[31mError: invalid image path "{}"\33[0m'.format(self.image_path))
            return
        ofs = open(self.output_file, 'w')

        # 2. traverse and save result to file
        names = self.obtain_file_names(self.image_path, 'jpg')
        # print(names)
        for timestamp, name in names:
            exit = self.click_rectangle(timestamp, name)
            if exit == True:
                break

            # check and save result
            if len(self.rec_pts) > 0 and len(self.rec_pts) % 2 == 0:
                while True:
                    check = self.check_rectangle(timestamp, name)
                    if check == True:
                        ofs.write(str(timestamp))
                        for pt in self.rec_pts:
                            ofs.write(" " + str(pt[0]) + " " + str(pt[1]))
                        ofs.write("\n")
                        break
                    else:
                        exit = self.click_rectangle(timestamp, name)
                        if exit == True:
                            exit(0)

    def obtain_file_names(self, image_path, suffix):
        res = []
        for _, _, names in os.walk(image_path):
            names.sort(key=lambda n: int(n.split('.')[0]))
            for name in names:
                if name.split('.')[-1] == suffix:
                    res.append(((float(name.split('.')[0]) / 1e6), os.path.join(image_path, name)))
            break
        return res

    def click_and_crop(self, event, x, y, flags, param):
        if event == cv2.EVENT_LBUTTONDOWN:
            self.rec_pts.append((x, y))
        elif event == cv2.EVENT_LBUTTONUP:
            self.rec_pts.append((x, y))
            # draw a rectangle around the region of interest
            if len(self.rec_pts) >= 2:
                cv2.rectangle(self.image, self.rec_pts[-2], self.rec_pts[-1], (0, 255, 0), 2)
                cv2.imshow("image", self.image)

    def click_rectangle(self, timestamp, name):
        exit = False
        self.image = cv2.imread(name)
        clone = self.image.copy()
        cv2.namedWindow("image")
        cv2.setMouseCallback("image", self.click_and_crop)
        self.rec_pts = []
        while True:
            cv2.putText(self.image, str(timestamp), (5,50), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)
            cv2.putText(self.image, "please click left top and right bottom (c: ok and next, q: exit)", (5,100),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)
            cv2.imshow("image", self.image)
            key = cv2.waitKey(1) & 0xFF
            if key == ord("r"):
                self.image = clone.copy()
                self.rec_pts = []
            elif key == ord("c"):
                break
            elif key == ord("q"):
                exit = True
                break
        cv2.destroyAllWindows()
        return exit

    def check_rectangle(self, timestamp, name):
        check = False
        cv2.namedWindow("check")
        img = cv2.imread(name)
        for i in range(0, len(self.rec_pts), 2):
            cv2.rectangle(img, self.rec_pts[i], self.rec_pts[i + 1], (0, 0, 255), 2)
        while True:
            cv2.putText(img, str(timestamp), (5,50), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)
            cv2.putText(img, "please check (c: ok and next, x: do it again)", (5,100),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)
            cv2.imshow("check", img)
            key = cv2.waitKey(1) & 0xFF
            if key == ord("c"):
                check = True
                break
            elif key == ord("x"):
                check = False
                break
        return check

if __name__=="__main__":
    ap = argparse.ArgumentParser()
    ap.add_argument("-i", "--image_path", required=True, help="Path to the image")
    ap.add_argument("-o", "--output_file", required=True, help="output_path")
    args = ap.parse_args()

    rec_select = RectangularSelection(args.image_path, args.output_file)
    rec_select.run()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于卷积自编码器和图像金字塔的布料缺陷检测python源码.zip 【资源介绍】 该项目是个人毕设项目,答辩评审分达到95分,代码都经过调试测试,确保可以运行!欢迎下载使用,可用于小白学习、进阶。 该资源主要针对计算机、通信、人工智能、自动化等相关专业的学生、老师或从业者下载使用,亦可作为期末课程设计、课程大作业、毕业设计等。 项目整体具有较高的学习借鉴价值!基础能力强的可以在此基础上修改调整,以实现不同的功能。 基于论文《An Unsupervised Learning Based Approach for Automated Defect Inspection on Textured Surfaces》进行复现实验验证,在自建无纺布匹数据集上进行训练和检测。 因为对缺陷进行标记或像素级分割很困难,缺陷的类型也十分复杂,所以基于学习的纹理缺陷检测大体思路是无监督的。即利用无监督学习算法学习正常纹理的数据分布特征,而不学习缺陷的数据分布特征。在待测图上以滑动区域为重构对象,与原图像做残差。由于正常纹理学习充分,重构残差应当很小,而缺陷区域的残差较大,故被凸现出来,随后再利用残差图做进一步处理。 在空域上进行无监督学习主要用卷积自编码器,其有两部分组成,编码器和解码器。编码器由卷积、激活、池化操作做成,对原始数据域分层做特征提取和降维,最后将数据映射到一个欠完备的隐层特征空间上。解码器由上采样、卷积、激活操作完成,将特征空间上的数据映射回空域。 本文主要功能实现:使用训练好的多尺度降噪自编码器对图像patch进行预测,将生成的图像patch与原始输入的patch进行对比,计算其重构残差,由于自编码器训练过程使用的是无缺陷的图像,因而自编码器会对有缺陷的图像patch更加敏感,致使残差值偏高,将残差值与训练集的统计量进行比对,根据设置的阈值来判断当前像素位置是否为缺陷,从而实现像素级的缺陷检测。 ## 模型及实现介绍 使用无瑕疵的训练集,在不同的图像金字塔尺度上(使用高斯金字塔,金字塔尺寸为512,256,128)训练一个自编码器(包含一个Decoder和Encoder),将原始图像裁剪为8*8的图像patch块,然后对其添加噪声,使用自编码器对这些图像patch进行处理,计算自编码器对每个图像patch的重建输出x’与输入x的残差|x-x’|,然后使用在不同金字塔尺度下设定好的阈值,来对重构残差进行判断,当存在多个尺度下的残差都超过阈值就认为该像素区域为缺陷像素。 1.数据收集和处理部分。** **数据收集:**使用的数据为先前项目使用的实际无纺布图像数据,原始图像为6800*8000,使用python脚本将其裁剪为多个512*512的图像。该步骤使用的脚本为cropImage.py。 **光照归一化:**由于数据图像本身光照足够,本文没有进行光照归一化,另一个原因是根据论文给出的韦伯光照归一化公式,使用代码复现后发现效果不佳,无法还原至论文的效果,代码为WLD.py。 **加入噪声:**使用椒盐噪声进行噪声腐蚀,噪声系数为0.01。相关代码位于utils.py **图像金字塔和Patch提取:**使用opencv构建图像金字塔,然后将每个层级的图像裁剪为8*8的图像patch,然后保存为训练数据集。相关代码位于preprocess.py 测试和结果** 测试图像不需要进行噪声腐蚀,直接输入原始图像进行残差计算。每个像素都对应一个patch图作为残差信息来源,通过该值与阈值进行比对,来确定该像素是否符合正常分布,如果超过阈值则认为该像素邻域为缺陷分布,除此之外,还需要根据不同尺度下的残差阈值,综合判断该像素邻域是否为缺陷特征,实验认为超过当达到两个尺度下都超过阈值,就认为该像素邻域为缺陷。 原论文并没有介绍如何将三个尺度的残差进行融合,因此本文采取的方案是使用多个尺度下训练的模型进行推理,并根据相应的结果使用RGB三个颜色通道来表示当前像素邻域的缺陷情况。 相关代码为test.py。 实验的瑕疵能够被正确的检测出来,平均来看,使用多尺度进行检测能够加准确地实现像素级检测,并且使用无监督方法不需要人工进行繁重的缺陷标注工作,与有监督学习的方式比较,该方法更便捷和可行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值