sort是list的方法,sorted对可迭代的序列都可以排序,所以对list,dict都可以排序,本文着重讲解字典下key和value都是变量下的排序,并附上工程时的代码
在做图像处理时,想找到截取图片轮廓内的部分占截取图片的最佳比例,这里用到了sorted排序
def bili(img):
gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
ret, binary_img = cv2.threshold(gray_img, 75, 255, cv2.THRESH_BINARY)
# binary_img = cv2.erode(binary_img, None, iterations=4)
# binary_img = cv2.dilate(binary_img, None, iterations=4)
(contours, hierarchy) = cv2.findContours(binary_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
(x, y, w, h) = cv2.boundingRect(contour) ## 找出轮廓包围的矩形框
# print(contour)
bili = w * h / (115.0 * 40.0)
return bili
def zuijia_xy(frame,zuijia_bili):
dict_bili = {}
for x in range(245, 255, 2):
for y in range(47, 57, 2):
crop_img = jie_qu(frame, (x, y), 115, 40)
crop_bili = bili(crop_img)
abs_bili = abs(crop_bili - zuijia_bili)
key = (x, y)
value = abs_bili
dict_bili[key] = value
# print(dict_bili)
sort_dict = sorted(dict_bili.items(), key=lambda item: item[1])
x = sort_dict[0][0][0]
y = sort_dict[0][0][1]
# print(x,y,sort_dict[1]) sort_dict[1]已经是第二个键值对
return x, y
这里bili函数返回计算二值化后的轮廓占截取图片的比例。函数zuijia_xy是返回最佳比例的左上角坐标,有x,y,w,h就可以截取我们想要的轮廓占比最好的图片。
代码如上:对key和value都是变量的代码可以使用`key = (x, y)和value = abs(crop_bili - zuijia_bili)得到key和value都是变量的字典。
之后使用items()方法将字典的元素 转化为了元组,而这里key参数对应的lambda表达式的意思则是选取元组中的第二个元素作为比较参数,在这里元组中第一个值是key即(x,y),第二个值是value的值,所以采用key=lambda item: item[1]这种可以对字典的value进行排序。如果采用key=lambda item: item[0][0]则是对(x,y)的x进行排序。注意排序后的返回值是一个list,而原字典中的名值对被转换为了list中的元组。
排序完后进行取值,sort_dict[0]是第一个键值对,以此类推。sort_dict[0][0]是第一个键值对的key值,即是一个元组,sort_dict[0][1]是value的值。sort_dict[0][0][0]是第一个键值对的第一个元素中的第一个值,在这里即是x的值
还可参考:sorted对key和value的排序
1.sorted函数按key值对字典排序
先来基本介绍一下sorted函数,sorted(iterable,key,reverse),sorted一共有iterable,key,reverse这三个参数。
其中iterable表示可以迭代的对象,例如可以是 dict.items()、dict.keys()等,key是一个函数,用来选取参与比较的元素,reverse则是用来指定排序是倒序还是顺 序,reverse=true则是倒序,reverse=false时则是顺序,默认时reverse=false。
要按key值对字典排序,则可以使用如下语句:
直接使用sorted(d.keys())就能按key值对字典排序,这里是按照顺序对key值排序的,如果想按照倒序排序的话,则只要将reverse置为true即可。
2.sorted函数按value值对字典排序
要对字典的value排序则需要用到key参数,在这里主要提供一种使用lambda表达式的方法,如下:
这里的d.items()实际上是将d转换为可迭代对象,迭代对象的元素为 (‘lilee’,25)、(‘wangyan’,21)、(‘liqun’,32)、(‘lidaming’,19),items()方法将字典的元素 转化为了元组,而这里key参数对应的lambda表达式的意思则是选取元组中的第二个元素作为比较参数(如果写作key=lambda item:item[0]的话则是选取第一个元素作为比较对象,也就是key值作为比较对象。lambda x:y中x表示输出参数,y表示lambda 函数的返回值),所以采用这种方法可以对字典的value进行排序。注意排序后的返回值是一个list,而原字典中的名值对被转换为了list中的元组。