├── README.md ├── VeRi.pkl ├── images └── background.jpg ├── imgs ├── error_judge.jpg ├── example1.jpg ├── example2.jpg ├── example3.jpg ├── example4.jpg ├── example5.jpg ├── example6.jpg ├── example8.jpg ├── system_input.jpg ├── system_intro.jpg └── system_load.jpg └── visualize.py /README.md: -------------------------------------------------------------------------------- 1 | # reid visual system 2 | 3 | ## 使用方法 4 | 1. 参考[https://github.com/BravoLu/open-VehicleReID/blob/master/evaluators/base.py](https://github.com/BravoLu/open-VehicleReID/blob/master/evaluators/base.py)#74~99行生成对应的.pkl文件。 5 | 6 | 2. 运行脚本,并指定数据集的位置 7 | ```shell 8 | python visualize.py -data ${data_path} 9 | ``` 10 | 11 | 3. 输入生成的.pkl文件,不带后缀,然后点击load键。 12 | ![pic](imgs/system_input.jpg) 13 | ![pic](imgs/system_load.jpg) 14 | 15 | 16 | 4. 可视化结果展示 17 | ![pic](imgs/example1.jpg) 18 | ![pic](imgs/example2.jpg) 19 | ![pic](imgs/example3.jpg) 20 | ![pic](imgs/example4.jpg) -------------------------------------------------------------------------------- /VeRi.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BravoLu/ReidVisualSystem/5bd7ebffd00798edb7ae87099bb87073ceb7996e/VeRi.pkl -------------------------------------------------------------------------------- /images/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BravoLu/ReidVisualSystem/5bd7ebffd00798edb7ae87099bb87073ceb7996e/images/background.jpg -------------------------------------------------------------------------------- /imgs/error_judge.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BravoLu/ReidVisualSystem/5bd7ebffd00798edb7ae87099bb87073ceb7996e/imgs/error_judge.jpg -------------------------------------------------------------------------------- /imgs/example1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BravoLu/ReidVisualSystem/5bd7ebffd00798edb7ae87099bb87073ceb7996e/imgs/example1.jpg -------------------------------------------------------------------------------- /imgs/example2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BravoLu/ReidVisualSystem/5bd7ebffd00798edb7ae87099bb87073ceb7996e/imgs/example2.jpg -------------------------------------------------------------------------------- /imgs/example3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BravoLu/ReidVisualSystem/5bd7ebffd00798edb7ae87099bb87073ceb7996e/imgs/example3.jpg -------------------------------------------------------------------------------- /imgs/example4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BravoLu/ReidVisualSystem/5bd7ebffd00798edb7ae87099bb87073ceb7996e/imgs/example4.jpg -------------------------------------------------------------------------------- /imgs/example5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BravoLu/ReidVisualSystem/5bd7ebffd00798edb7ae87099bb87073ceb7996e/imgs/example5.jpg -------------------------------------------------------------------------------- /imgs/example6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BravoLu/ReidVisualSystem/5bd7ebffd00798edb7ae87099bb87073ceb7996e/imgs/example6.jpg -------------------------------------------------------------------------------- /imgs/example8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BravoLu/ReidVisualSystem/5bd7ebffd00798edb7ae87099bb87073ceb7996e/imgs/example8.jpg -------------------------------------------------------------------------------- /imgs/system_input.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BravoLu/ReidVisualSystem/5bd7ebffd00798edb7ae87099bb87073ceb7996e/imgs/system_input.jpg -------------------------------------------------------------------------------- /imgs/system_intro.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BravoLu/ReidVisualSystem/5bd7ebffd00798edb7ae87099bb87073ceb7996e/imgs/system_intro.jpg -------------------------------------------------------------------------------- /imgs/system_load.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BravoLu/ReidVisualSystem/5bd7ebffd00798edb7ae87099bb87073ceb7996e/imgs/system_load.jpg -------------------------------------------------------------------------------- /visualize.py: -------------------------------------------------------------------------------- 1 | # This is a visualization tool of vehicle re-identification. 2 | # Step 1: Save the matched test image IDs for each query image as a text file, where each line contains a test image ID ranked in terms of distance score in ascending order. Name each text file as '%06d.txt' % . We assume that the top-35 matched test images are displayed. An example is given in "./dist_example/". 3 | # Step 2: Run "python visualize.py". 4 | # Step 3: Input the path of the directory containing all text files at "Txt Dir:" (end with '/'). An example is given as "./dist_example/". 5 | # Step 4: Click "Load". 6 | # The query image is shown on the top left. The corresponding test images are shown on the right. 7 | # For each image, the image ID is shown on the top left corner. 8 | # Click "<< Prev" to return to the previous query. 9 | # Click "Next >>" to advance to the next query. 10 | # Enter the query no. and click "Go" to jump to the corresponding query. 11 | 12 | from __future__ import division 13 | from __future__ import print_function 14 | from tkinter import * 15 | #import tkMessageBox 16 | 17 | import argparse 18 | import pickle 19 | from PIL import Image, ImageTk 20 | import os 21 | import glob 22 | import cv2 23 | import numpy as np 24 | from collections import defaultdict 25 | 26 | parser = argparse.ArgumentParser('Rank List') 27 | parser.add_argument('-d', '--data', type=str) 28 | args = parser.parse_args() 29 | 30 | DATA_PATH = args.data 31 | 32 | # image sizes for the examples 33 | SIZE = 256, 256 34 | 35 | def load_pickle(path): 36 | with open(path, 'rb') as f: 37 | dicts = pickle.load(f) 38 | return dicts 39 | 40 | def num_per_id(): 41 | imgs = os.listdir('../image_test') 42 | gallery_num = defaultdict(int) 43 | for img in imgs: 44 | ID = img[0:4] 45 | gallery_num[ID] += 1 46 | 47 | return gallery_num 48 | 49 | gallery_num = num_per_id() 50 | 51 | class VisTool(): 52 | def __init__(self, master): 53 | # set up the main frame 54 | self.parent = master 55 | self.parent.title("VisTool") 56 | self.frame = Frame(self.parent) 57 | self.frame['background'] = 'white' 58 | self.frame.pack(fill=BOTH, expand=1) 59 | self.parent.resizable(width=FALSE, height=FALSE) 60 | 61 | # initialize global state 62 | self.txtDir = '' 63 | self.txtList = [] 64 | self.prbList = [] 65 | self.outDir = '' 66 | self.cur = 0 67 | self.total = 0 68 | self.category = '' 69 | self.imagename = '' 70 | self.labelfilename = '' 71 | self.tkimg = None 72 | 73 | # ----------------- GUI stuff --------------------- 74 | # dir entry & load 75 | self.label = Label(self.frame, text="Rank File(.pkl):") 76 | self.label.grid(row=0, column=0, sticky=E) 77 | self.entry = Entry(self.frame) 78 | #self.info = Label(self.frame, text="info") 79 | #self.info.grid(row=1, column=1, sticky=W + E) 80 | self.entry.grid(row=0, column=1, sticky=W + E) 81 | self.ldBtn = Button(self.frame, text="Load", command=self.loadDir) 82 | self.ldBtn.grid(row=0, column=2, sticky=W + E) 83 | 84 | # main panel 85 | self.mainPanel = Canvas(self.frame, cursor='arrow') 86 | self.parent.bind("a", self.prevPrb) # press 'a' to go backforward 87 | self.parent.bind("d", self.nextPrb) # press 'd' to go forward 88 | self.mainPanel.grid(row=1, column=1, rowspan=4, sticky=W + N) 89 | 90 | # control panel for image navigation 91 | self.ctrPanel = Frame(self.frame) 92 | self.ctrPanel.grid(row=5, column=1, columnspan=2, sticky=W + E) 93 | self.prevBtn = Button(self.ctrPanel, text='<< Prev', width=10, command=self.prevPrb) 94 | self.prevBtn.pack(side=LEFT, padx=5, pady=3) 95 | self.nextBtn = Button(self.ctrPanel, text='Next >>', width=10, command=self.nextPrb) 96 | self.nextBtn.pack(side=LEFT, padx=5, pady=3) 97 | self.progLabel = Label(self.ctrPanel, text="Progress: / ") 98 | self.progLabel.pack(side=LEFT, padx=5) 99 | self.tmpLabel = Label(self.ctrPanel, text="Go to Query No.") 100 | self.tmpLabel.pack(side=LEFT, padx=5) 101 | self.idxEntry = Entry(self.ctrPanel, width=5) 102 | self.idxEntry.pack(side=LEFT) 103 | self.goBtn = Button(self.ctrPanel, text='Go', command=self.gotoPrb) 104 | self.goBtn.pack(side=LEFT) 105 | 106 | # panel for query image 107 | self.prbPanel = Frame(self.frame, border=10) 108 | self.prbPanel['background'] = 'white' 109 | self.prbPanel.grid(row=1, column=0, rowspan=5, sticky=N) 110 | self.tmpLabel2 = Label(self.prbPanel, text="Query image:") 111 | self.info = Label(self.prbPanel, text="info:") 112 | self.info.pack(side=BOTTOM, pady=10) 113 | self.info['background'] = 'white' 114 | self.tmpLabel2['background'] = 'white' 115 | self.tmpLabel2.pack(side=TOP, pady=5) 116 | self.prbLabels = [] 117 | self.prbLabels.append(Label(self.prbPanel)) 118 | self.prbLabels[-1].pack(side=TOP) 119 | 120 | # display mouse position 121 | self.disp = Label(self.ctrPanel, text='') 122 | self.disp.pack(side=RIGHT) 123 | 124 | self.frame.columnconfigure(1, weight=1) 125 | self.frame.rowconfigure(4, weight=1) 126 | 127 | def loadDir(self): 128 | #self.txtDir = os.path.join(self.entry.get()) 129 | self.rank_pkl = load_pickle(self.entry.get()+'.pkl') 130 | self.queries = list(self.rank_pkl.keys()) 131 | #self.txtList = glob.glob(os.path.join(self.txtDir, '*.txt')) 132 | #self.txtList.sort(key=lambda x: int(x[-10:-4])) 133 | 134 | if len(self.queries) == 0: 135 | print('No text file found in the specified directory!') 136 | return 137 | 138 | # default: the 1st image in the collection 139 | self.cur = 1 140 | self.total = len(self.queries) 141 | 142 | self.loadImage() 143 | print('%d images loaded' % self.total) 144 | 145 | def loadImage(self): 146 | 147 | query = self.queries[self.cur - 1] 148 | 149 | rank_list = [] 150 | 151 | rank_list.append(os.path.join(DATA_PATH, 'image_query', query)) 152 | 153 | for gallery in self.rank_pkl[query]: 154 | rank_list.append(os.path.join(DATA_PATH, 'image_test', gallery)) 155 | 156 | self.tmp = [] 157 | self.prbList = [] 158 | 159 | # load query image 160 | f = rank_list[0] 161 | print(f) 162 | gn = gallery_num[query[0:4]] 163 | self.info.config(text="gallery size: %d"%(gn)) 164 | im = cv2.imread(f) 165 | #cv2.imwrite('test.jpg', im) 166 | query_id = f[-24:-20] 167 | im = cv2.cvtColor(np.asarray(im), cv2.COLOR_BGR2RGB) 168 | im = Image.fromarray(im).resize((200, 200), Image.BILINEAR) 169 | #im = Image.fromarray(im).resize((200, 200), Image.ANTIALIAS) 170 | 171 | im = np.asarray(im) #cv2.cvtColor(np.asarray(im), cv2.COLOR_BGR2RGB) 172 | cv2.putText(im, f[-24:-4], (20,40), cv2.FONT_HERSHEY_COMPLEX,1,(255,0,0),1) 173 | #im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB) 174 | im_h, im_w = im.shape[:2] 175 | if (im_w + im_h) < 100: 176 | thk = 2 177 | else: 178 | thk = int((im_w + im_h) / 50) 179 | # cv2.rectangle(im, (0, 0), ((im_w-1), (im_h-1)), (0,0,255), thk) 180 | im = Image.fromarray(im) 181 | #im = im.convert('RBG') 182 | r = min(SIZE[0] / im.size[0], SIZE[1] / im.size[1]) 183 | new_size = int(r * im.size[0]), int(r * im.size[1]) 184 | self.tmp.append(im.resize(new_size, Image.ANTIALIAS)) 185 | self.prbList.append(ImageTk.PhotoImage(self.tmp[-1])) 186 | self.prbLabels[0].config(image=self.prbList[-1], width=SIZE[0], height=SIZE[1]) 187 | 188 | # load gallery images 189 | rank_list = rank_list[1:] 190 | siz = len(rank_list) 191 | siz = min(siz, 35) 192 | myrange = np.array(range(siz)) 193 | myrange = myrange + 35 * 0 194 | myimage = [] 195 | for i in myrange: 196 | print(rank_list[i]) 197 | im = cv2.imread(rank_list[i]) 198 | im = cv2.cvtColor(np.asarray(im), cv2.COLOR_BGR2RGB) 199 | im = Image.fromarray(im).resize((200, 200), Image.BILINEAR) 200 | im = np.asarray(im) 201 | gallery_id = rank_list[i][-24:-20] 202 | if query_id == gallery_id: 203 | cv2.rectangle(im,(2,2),(im.shape[1]-2,im.shape[0]-2),(0,255,0),2) 204 | else: 205 | cv2.rectangle(im,(2,2),(im.shape[1]-2,im.shape[0]-2),(255,0,0),2) 206 | cv2.putText(im, rank_list[i][-24:-4], (5,40), cv2.FONT_HERSHEY_COMPLEX, 0.5, (255,0,0),1) 207 | 208 | im_h, im_w = im.shape[:2] 209 | if (im_w + im_h) < 100: 210 | thk = 2 211 | else: 212 | thk = int((im_w + im_h) / 50) 213 | 214 | # if p_id == g_id: 215 | # cv2.rectangle(im, (0, 0), ((im_w-1), (im_h-1)), (0,255,0), thk) 216 | # else: 217 | # cv2.rectangle(im, (0, 0), ((im_w-1), (im_h-1)), (255,0,0), thk) 218 | ''' 219 | if im.shape[0] > im.shape[1]: 220 | myimage.append(Image.fromarray(im).resize((int(200 * im.shape[1] / im.shape[0]), 200), Image.ANTIALIAS)) 221 | else: 222 | myimage.append(Image.fromarray(im).resize((200, int(200 * im.shape[0] / im.shape[1])), Image.ANTIALIAS)) 223 | ''' 224 | myimage.append(Image.fromarray(im)) 225 | self.img = Image.new('RGB', (1400, 180 * 5)) 226 | 227 | ss = 7 228 | for i in range(siz): 229 | row = int(i / ss) 230 | tlx = (i - ss * row) * 200 231 | tly = 180 * row 232 | shape = myimage[i].size 233 | self.img.paste(myimage[i], (tlx, tly, tlx + shape[0], tly + shape[1])) 234 | 235 | self.tkimg = ImageTk.PhotoImage(self.img) 236 | self.mainPanel.config(width=max(self.tkimg.width(), 1000), height=max(self.tkimg.height(), 400)) 237 | self.mainPanel.create_image(0, 0, image=self.tkimg, anchor=NW) 238 | self.progLabel.config(text="%04d/%04d" % (self.cur, self.total)) 239 | 240 | def prevPrb(self, event=None): 241 | if self.cur > 1: 242 | self.cur -= 1 243 | self.loadImage() 244 | 245 | def nextPrb(self, event=None): 246 | if self.cur < self.total: 247 | self.cur += 1 248 | self.loadImage() 249 | 250 | def gotoPrb(self): 251 | idx = int(self.idxEntry.get()) 252 | if 1 <= idx and idx <= self.total: 253 | self.cur = idx 254 | self.loadImage() 255 | 256 | 257 | if __name__ == '__main__': 258 | root = Tk() 259 | tool = VisTool(root) 260 | root.resizable(width=True, height=True) 261 | root.mainloop() 262 | --------------------------------------------------------------------------------