1. 程式人生 > >影象擴充用於影象目標檢測

影象擴充用於影象目標檢測

常用的影象擴充方式有: 水平翻轉,裁剪,視角變換,jpeg壓縮,尺度變換,顏色變換,旋轉 當用於分類資料集時,這些變換方法可以全部被使用,然而考慮到目標檢測標註框的變換,我們選擇如下幾種方式用於目標檢測資料集擴充: jpeg壓縮,尺度變換,顏色變換 這裡,我們介紹一個圖象變換包 這是專案主頁,裡面介紹了用於影象變換的基本方法,以及如何組合它們可以得到最好的效果,專案主頁裡同時帶python程式。

裡面的影象變換程式如下(用於windows下,用於目標檢測時,做了一些修改):

import os, sys, pdb, numpy
from PIL import Image,ImageChops,ImageOps,ImageDraw

#parameters used for the CVPR paper
NCROPS = 10
NHOMO = 8
JPG=[70,50,30]
ROTS = [3,6,9,12,15]
SCALES=[1.5**0.5,1.5,1.5**1.5,1.5**2,1.5**2.5]
#parameters computed on ILSVRC10 dataset
lcolor = [ 381688.61379382 , 4881.28307136,  2316.10313483]
pcolor = [[-0.57848371, -0.7915924,   0.19681989],
          [-0.5795621 ,  0.22908373, -0.78206676],
          [-0.57398987 , 0.56648223 , 0.59129816]]

#pre-generated gaussian values
alphas = [[0.004894 , 0.153527, -0.012182],
          [-0.058978, 0.114067, -0.061488],
          [0.002428, -0.003576, -0.125031]]

def gen_colorimetry(i):
    p1r = pcolor[0][0]
    p1g = pcolor[1][0]
    p1b = pcolor[2][0]
    p2r = pcolor[0][1]
    p2g = pcolor[1][1]
    p2b = pcolor[2][1]
    p3r = pcolor[0][2]
    p3g = pcolor[1][2]
    p3b = pcolor[2][2]

    l1 = numpy.sqrt(lcolor[0])
    l2 = numpy.sqrt(lcolor[1])
    l3 = numpy.sqrt(lcolor[2])

    if i<=3:
        alpha = alphas[i]
    else:
        numpy.random.seed(i*3)
        alpha = numpy.random.randn(3,0,0.01)
    a1 = alpha[0]
    a2 = alpha[1]
    a3 = alpha[2]

    return (a1*l1*p1r + a2*l2*p2r + a3*l3*p3r,
            a1*l1*p1g + a2*l2*p2g + a3*l3*p3g,
            a1*l1*p1b + a2*l2*p2b + a3*l3*p3b)

def gen_crop(i,w,h):
    numpy.random.seed(4*i)
    x0 = numpy.random.random()*(w/4)
    y0 = numpy.random.random()*(h/4)
    x1 = w - numpy.random.random()*(w/4)
    y1 = h - numpy.random.random()*(h/4)

    return (int(x0),int(y0),int(x1),int(y1))

def gen_homo(i,w,h):
    if i==0:
        return (0,0,int(0.125*w),h,int(0.875*w),h,w,0)
    elif i==1:
      return (0,0,int(0.25*w),h,int(0.75*w),h,w,0)
    elif i==2:
        return (0,int(0.125*h),0,int(0.875*h),w,h,w,0)
    elif i==3:
      return (0,int(0.25*h),0,int(0.75*h),w,h,w,0)
    elif i==4:
        return (int(0.125*w),0,0,h,w,h,int(0.875*w),0)
    elif i==5:
        return (int(0.25*w),0,0,h,w,h,int(0.75*w),0)
    elif i==6:
        return (0,0,0,h,w,int(0.875*h),w,int(0.125*h))
    elif i==7:
        return (0,0,0,h,w,int(0.75*h),w,int(0.25*h))
    else:
        assert False


def rot(image,angle,fname):
    white = Image.new('L',image.size,"white")
    wr = white.rotate(angle,Image.NEAREST,expand=0)
    im = image.rotate(angle,Image.BILINEAR,expand=0)
    try:
      image.paste(im,wr)
    except ValueError:
      print >>sys.stderr, 'error: image do not match '+fname
    return image

def gen_corner(n, w, h):
    x0 = 0
    x1 = w
    y0 = 0
    y1 = h
    
    rat = 256 - 227

    if n == 0: #center
        x0 = (rat*w)/(2*256.0)
        y0 = (rat*h)/(2*256.0)
        x1 = w - (rat*w)/(2*256.0)
        y1 = h - (rat*h)/(2*256.0)
    elif n == 1:
        x0 = (rat*w)/256.0
        y0 = (rat*h)/256.0
    elif n == 2:
        x1 = w - (rat*w)/256.0
        y0 = (rat*h)/256.0
    elif n == 3:
        x1 = w - (rat*w)/256.0
        y1 = h - (rat*h)/256.0
    else:
        assert n==4
        x0 = (rat*w)/256.0
        y1 = h - (rat*h)/256.0

    return (int(x0),int(y0),int(x1),int(y1))

#the main fonction to call
#takes a image input path, a transformation and an output path and does the transformation
def gen_trans(imgfile,trans,outfile):
    for trans in trans.split('*'):
        image = Image.open(imgfile)
        w,h = image.size
        if trans=="plain":
            image.save(outfile,"JPEG",quality=100)
        elif trans=="flip":
            ImageOps.mirror(image).save(outfile,"JPEG",quality=100)
        elif trans.startswith("crop"):
            c = int(trans[4:])
            image.crop(gen_crop(c,w,h)).save(outfile,"JPEG",quality=100)
        elif trans.startswith("homo"):
            c = int(trans[4:])
            image.transform((w,h),Image.QUAD,
                            gen_homo(c,w,h),
                            Image.BILINEAR).save(outfile,"JPEG",quality=100)
        elif trans.startswith("jpg"):
            image.save(outfile,quality=int(trans[3:]))
        elif trans.startswith("scale"):
            scale = SCALES[int(trans.replace("scale",""))]
            image.resize((int(w/scale),int(h/scale)),Image.BILINEAR).save(outfile,"JPEG",quality=100)
        elif trans.startswith('color'):
            (dr,dg,db) = gen_colorimetry(int(trans[5]))
            table = numpy.tile(numpy.arange(256),(3))
            table[   :256]+= (int)(dr)
            table[256:512]+= (int)(dg)
            table[512:   ]+= (int)(db)
            image.convert("RGB").point(table).save(outfile,"JPEG",quality=100)
        elif trans.startswith('rot-'):
            angle =int(trans[4:])
            for i in range(angle):
                image = rot(image,-1,outfile)
            image.save(outfile,"JPEG",quality=100)
        elif trans.startswith('rot'):
            angle =int(trans[3:])
            for i in range(angle):
                image = rot(image,1,outfile)
            image.save(outfile,"JPEG",quality=100)
        elif trans.startswith('corner'):
            i = int(trans[6:])
            image.crop(gen_corner(i,w,h)).save(outfile,"JPEG",quality=100)
        else:
            assert False, "Unrecognized transformation: "+trans
        imgfile = outfile # in case we iterate


#Our 41 transformations used in the CVPR paper
def get_all_trans():
  # transformations = (["plain","flip"]
  #                  # +["crop%d"%i for i in range(NCROPS)]
  #                  # +["homo%d"%i for i in range(NHOMO)]
  #                   +["jpg%d"%i for i in JPG]
  #                   +["scale0","scale1","scale2","scale3","scale4"]
  #                   +["color%d"%i for i in range(3)]
  #                  # +["rot-%d"%i for i in ROTS]
  #                   # +["rot%d"%i for i in ROTS]
  # )+["scale0","scale1","scale2","scale3","scale4"]
  transformations=(["plain"]
                   + ["jpg%d" % i for i in JPG]
                   + ["scale0", "scale1", "scale2", "scale3", "scale4"]
                   + ["color%d" % i for i in range(3)])
  return transformations

#transformations used at test time in deep architectures
def get_deep_trans():
    return ['corner0','corner1','corner2','corner3','corner4','corner0*flip','corner1*flip','corner2*flip','corner3*flip','corner4*flip']

if __name__=="__main__":
    inputpath = sys.argv[1]
    name = [name for name in os.listdir(inputpath) if os.path.isfile(os.path.join(inputpath,name))]
    #img_input = sys.argv[1]
    outpath = sys.argv[2]
    if len(sys.argv)>= 4:
        trans = sys.argv[3]
        if not trans.startswith("["):
            trans = [trans]
        else:
            trans = eval(trans)
    else:
        trans = get_all_trans()
    print "Generating transformations and storing in %s"%(outpath)
    for k in name:
        for t in trans:
            img_input=inputpath+'\\'+k
            gen_trans(img_input,t,outpath+'\\%s_%s.jpg'%(".".join(img_input.split("\\")[-1].split(".")[:-1]),t))
            #gen_trans(k, t, outpath + '\\%s_%s.jpg' % (".".join(k.split(".")[:-1]), t))
    print "Finished. Transformations generated: %s"%(" ".join(trans))
這是變換前的圖片:1._7_17.jpg
變換後的圖片如下: 1_7_17_color0.jpg
1_7_17_color1.jpg
1_7_17_color2.jpg
1_7_17_jpg30.jpg
1_7_17_jog50.jpg
1_7_17_jpg70.jpg
1_7_17_scale0.jpg
1_7_17_scale1.jpg
1_7_17_scale2.jpg
1_7_17_scale3.jpg
1_7_17_scale4.jpg
用於目標檢測時:XML標註檔案也需要做相應修改,主要是針對尺度變換: 修改前的xml檔案如下(1_7_17.jpg):
<annotation>
	<folder>spl</folder>
	<filename>1_7_17.jpg</filename>
	<source>
		<database>The spl Database</database>
		<annotation>The spl Database</annotation>
		<image>spl</image>
		<flickrid>0</flickrid>
	</source>
	<owner>
		<flickrid>spl</flickrid>
		<name>xiaovv</name>
	</owner>
	<size>
		<width>800</width>
		<height>800</height>
		<depth>3</depth>
	</size>
	<segmented>0</segmented>
	<object>
		<name>aeroplane</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>151</xmin>
			<ymin>357</ymin>
			<xmax>212</xmax>
			<ymax>399</ymax>
		</bndbox>
	</object>
	<object>
		<name>aeroplane</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>134</xmin>
			<ymin>593</ymin>
			<xmax>193</xmax>
			<ymax>654</ymax>
		</bndbox>
	</object>
</annotation>
修改後的xml檔案如下(1_7_17_scale4.jpg):
<?xml version="1.0" encoding="utf-8"?><annotation>
	<folder>spl</folder>
	<filename>1_7_17_scale4.jpg</filename>
	<source>
		<database>The spl Database</database>
		<annotation>The spl Database</annotation>
		<image>spl</image>
		<flickrid>0</flickrid>
	</source>
	<owner>
		<flickrid>spl</flickrid>
		<name>xiaovv</name>
	</owner>
	<size>
		<width>290</width>
		<height>290</height>
		<depth>3</depth>
	</size>
	<segmented>0</segmented>
	<object>
		<name>aeroplane</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>54</xmin>
			<ymin>129</ymin>
			<xmax>76</xmax>
			<ymax>144</ymax>
		</bndbox>
	</object>
	<object>
		<name>aeroplane</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>48</xmin>
			<ymin>215</ymin>
			<xmax>70</xmax>
			<ymax>237</ymax>
		</bndbox>
	</object>
</annotation>
修改xml檔案的程式如下;
# -*- coding=utf-8 -*-
import os
import sys
import shutil
from xml.dom.minidom import Document
from xml.etree.ElementTree import ElementTree,Element
import  xml.dom.minidom
JPG=[70,50,30]
SCALES=[1.5**0.5,1.5,1.5**1.5,1.5**2,1.5**2.5]

#產生變換後的xml檔案
def gen_xml(xml_input,trans,outfile):
    for trans in trans.split('*'):
        if trans=="plain" or trans.startswith("jpg") or trans.startswith('color'):#如果是這幾種變換,直接修改xml檔名就好
            dom = xml.dom.minidom.parse(xml_input)
            root = dom.documentElement
            filenamelist = root.getElementsByTagName('filename')
            filename = filenamelist[0]
            c = str(filename.firstChild.data)
            d = ".".join(outfile.split("\\")[-1].split(".")[:-1]) + '.jpg'
            filename.firstChild.data = d
            f = open(outfile, 'w')
            dom.writexml(f, encoding='utf-8')
        elif trans.startswith("scale"):#對於尺度變換,xml檔案資訊也需要改變
            scale = SCALES[int(trans.replace("scale", ""))]
            dom=xml.dom.minidom.parse(xml_input)
            root=dom.documentElement
            filenamelist=root.getElementsByTagName('filename')
            filename=filenamelist[0]
            c=str(filename.firstChild.data)
            d=".".join(outfile.split("\\")[-1].split(".")[:-1])+'.jpg'
            filename.firstChild.data=d
            heightlist = root.getElementsByTagName('height')
            height = heightlist[0]
            a = int(height.firstChild.data)
            b = str(int(a / scale))
            height.firstChild.data = b
            widthlist=root.getElementsByTagName('width')
            width=widthlist[0]
            a = int(width.firstChild.data)
            b = str(int(a / scale))
            width.firstChild.data=b
            objectlist=root.getElementsByTagName('xmin')
            for object in objectlist:
                a=int(object.firstChild.data)
                b=str(int(a/scale))
                object.firstChild.data=b
            objectlist = root.getElementsByTagName('ymin')
            for object in objectlist:
                a = int(object.firstChild.data)
                b = str(int(a / scale))
                object.firstChild.data = b
            objectlist = root.getElementsByTagName('xmax')
            for object in objectlist:
                a = int(object.firstChild.data)
                b = str(int(a / scale))
                object.firstChild.data = b
            objectlist = root.getElementsByTagName('ymax')
            for object in objectlist:
                a = int(object.firstChild.data)
                b = str(int(a / scale))
                object.firstChild.data = b
            f=open(outfile,'w')
            dom.writexml(f,encoding='utf-8')
        else:
            assert False, "Unrecognized transformation: "+trans

#產生各種變換名
def get_all_trans():
  transformations=(["plain"]
                   + ["jpg%d" % i for i in JPG]
                   + ["scale0", "scale1", "scale2", "scale3", "scale4"]
                   + ["color%d" % i for i in range(3)])
  return transformations

if __name__=="__main__":
    inputpath = sys.argv[1]
    name = [name for name in os.listdir(inputpath) if os.path.isfile(os.path.join(inputpath,name))]
    outpath = sys.argv[2]
    if len(sys.argv)>= 4:
        trans = sys.argv[3]
        if not trans.startswith("["):
            trans = [trans]
        else:
            trans = eval(trans)
    else:
        trans = get_all_trans()
    print "Generating transformations and storing in %s"%(outpath)
    for k in name:
        for t in trans:
            xml_input=inputpath+'\\'+k
            gen_xml(xml_input,t,outpath+'\\%s_%s.xml'%(".".join(xml_input.split("\\")[-1].split(".")[:-1]),t))





相關推薦

影象擴充用於影象目標檢測

常用的影象擴充方式有: 水平翻轉,裁剪,視角變換,jpeg壓縮,尺度變換,顏色變換,旋轉 當用於分類資料集時,這些變換方法可以全部被使用,然而考慮到目標檢測標註框的變換,我們選擇如下幾種方式用於目標檢測資料集擴充: jpeg壓縮,尺度變換,顏色變換 這裡,我們介紹一個圖象變

影象標註工具彙總目標檢測標註工具影象分割標註工具

對於監督學習演算法而言,資料決定了任務的上限,而演算法只是在不斷逼近這個上限。世界上最遙遠的距離就是我們用同一個模型,但是卻有不同的任務。但是資料標註是個耗時耗力的工作,下面介紹幾個影象標註工具: Labelme Labelme適用於影象分割任務的資料集製作: 它來自下面的專案:https:

目標檢測影象分割簡要發展史

歡迎大家關注我們的網站和系列教程:http://www.tensorflownews.com/,學習更多的機器學習、深度學習的知識! by 小韓 (來源: https://blog.athelas.com/a-brief-history-of-cnns-in-ima

第十九節、基於傳統影象處理的目標檢測與識別(詞袋模型BOW+SVM附程式碼)

在上一節、我們已經介紹了使用HOG和SVM實現目標檢測和識別,這一節我們將介紹使用詞袋模型BOW和SVM實現目標檢測和識別。 一 詞袋介紹 詞袋模型(Bag-Of-Word)的概念最初不是針對計算機視覺的,但計算機視覺會使用該概念的升級。詞袋最早出現在神經語言程式學(NLP)和資訊檢索(IR)領域,該模型

pytorch 目標檢測 影象預處理

Faster RCNN 和Retinanet在將影象資料輸送到網路之前,要對影象資料進行預處理。大致上與部落格提到的相同。 事實上還可以採取第三步,將圖片的寬和高擴充套件為32的整倍數,正如在Retinanet使用的。下面是一個簡單的Pytorch資料預處理模組: class Resizer():

一文帶你學會使用YOLO及Opencv完成影象及視訊流目標檢測(上)|附原始碼

計算機視覺領域中,目標檢測一直是工業應用上比較熱門且成熟的應用領域,比如人臉識別、行人檢測等,國內的曠視科技、商湯科技等公司在該領域佔據行業領先地位。相對於影象分類任務而言,目標檢測會更加複雜一些,不僅需要知道這是哪一類影象,而且要知道影象中所包含的內容有什麼及其在影象中的位置,因此,其工業應用比較廣泛。那麼

影象分類和目標檢測常用資料集介紹

The Caltech-UCSD birds-200-2011 dataset(加利福尼亞理工學院鳥類資料集): 分類數量:200 圖片數量:11,788 每個影象的註釋:15個部分位置,312個二進位制屬性,1邊界框 Labeled faces in the wild: L

深度學習 --- CNN的變體在影象分類、影象檢測目標跟蹤、語義分割和例項分割的簡介(附論文連結)

以上就是卷積神經網路的最基礎的知識了,下面我們一起來看看CNN都是用在何處並且如何使用,以及使用原理,本人還沒深入研究他們,等把基礎知識總結完以後開始深入研究這幾個方面,然後整理在寫成部落格,最近的安排是後面把自然語言處理總結一下,強化學習的總結就先往後推一下。再往後是系統的學習一下演算法和資料

目標檢測+影象分割專案

【深度學習:目標檢測】RCNN學習筆記(10):SSD:Single Shot MultiBox Detector 2016年10月06日 19:00:10 蓀蓀 閱讀數:40730更多 之前一直想總結下SSD,奈何時間緣故一直沒有整理,在我的認知當中,S

目標檢測的xml目標繪製在影象

用xml.etree.ElementTree庫來解析xml檔案 1.解析:ET.parse() 2.獲取根節點:getroot() 3.找節點用find() 和findall() 4.    .text 是內容 #本程式碼用到.text    .tag 是題目

在opencv3中利用SVM進行影象目標檢測和分類

採用滑鼠事件,手動選擇樣本點,包括目標樣本和背景樣本。組成訓練資料進行訓練 1、主函式 #include "stdafx.h" #include "opencv2/opencv.hpp" using namespace cv; using namespace cv::ml; Mat img,image

影象目標檢測與跟蹤學習筆記(五)

        作者跟蹤的實現過程中,作者定義了兩個correlation filter,一個濾波器(translation filter)專門用於確定新的目標所處的位置,另一個濾波器(scale filter)專門用於尺度評估。在translation filter方面,作者的方法與MOSSE的方法是一樣的

影象分類,目標檢測,語義分割的FC的區別

還有半個月就要過年啦,提前給大夥拜個年哈哈,快放假了又進入了划水的階段啥都不太想幹,但是就算是划水也不能中斷思考啊,誰讓咱是搞技術的呢,過去的幾個月裡把語義分割,目標檢測和影象分類都稍微瞭解了一下,因為是入門階段所以聊得東西都比較簡單,這篇部落格就聊一聊這幾個任務在全連線層

目標檢測影象特徵提取之(四)OpenCV中BLOB特徵提取與幾何形狀分類

OpenCV中BLOB特徵提取與幾何形狀分類一:方法二值影象幾何形狀提取與分離,是機器視覺中重點之一,在CT影象分析與機器人視覺感知等領域應用廣泛,OpenCV中提供了一個對二值影象幾何特徵描述與分析最有效的工具 - SimpleBlobDetector類,使用它可以實現對二

影象目標檢測(Object Detection)原理與實現(三)

基於霍夫森林的目標檢測        上節說了霍夫變換(HT)和廣義霍夫變換(GHT),今天就接著廣義霍夫變換說下去,在廣義霍夫變換中,每個投票元素(比如邊緣畫素中的點)在霍夫空間中累加投票的權重是相等的,每個元素投票的權重互不影響,這其實是假設了影象空間中的每個畫

計算機視覺之目標檢測影象分割方法

1.目標檢測 現在的目標檢測方法主要分為三類: (1)基於傳統手工特徵的目標檢測方法 (2)基於RCNN的目標檢測方法 代表演算法有RCNN,SPP-Net, Fast-RCNN,Faster-RCNN (3)基於CNN迴歸的目標檢測方法 代表演算法

CS231n-2017 第11講 目標檢測影象分割

一、語義分割 將一張圖片中的畫素按類別區分。示例如下: 圖 1. 語義分割示例 語義分割不區分同類事物的不同例項。 語義分割的思路: 使用滑動窗方法,每次取影象的一部分,使用神經網路判斷此部分的中心畫素屬於

影象處理——目標檢測與前背景分離

前提     運動目標的檢測是計算機影象處理與影象理解領域裡一個重要課題,在機器人導航、智慧監控、醫學影象分析、視訊影象編碼及傳輸等領域有著廣泛的應用。                       

計算機視覺筆記及資料整理(含影象分割、目標檢測小方向學習)

前言 1、簡單聊聊: 在我腦海中我能通過這些年聽到的技術名詞來感受到技術的更新及趨勢,這種技術發展有時候我覺得連關注的腳步都趕不上。簡單回顧看看,從我能聽到的技術名詞來感受,最開始耳聞比較多「雲端計算」這玩意,後來聽到比較多的是「資料探勘」,當時想著等考上研也要

Matlab影象序列中的運動目標檢測與跟蹤

clc; clear; % close all; %%%%%%%%%%%%%%% 讀序列影象 %%%%%%%%%%% location = 'D:\ex7\';%資料夾位置 count=2; %影象幀數 % aviFileName = 'images2AVI.avi'; aviObj =avifile('i