名称 | 占用空间 | 内容 | 实际数据 |
---|---|---|---|
bfType | 2字节 | 标识,就是“BM”二字 | BM |
bfSize | 4字节 | 整个BMP文件的大小 | 0x0046b438(4633656) |
bfReserved1/2 | 4字节 | 保留字,占位 | 0x00000000 |
bfOffBits | 4字节 | 偏移数,即 位图文件头+位图信息头+调色板 的大小 | 0x00000036(54) |
注意,Windows的数据是倒着念的,这是PC电脑的特色。如果一段数据为50 1A 25 3C,倒着念就是3C 25 1A50,即0x3C251A50。因此,如果bfSize的数据为38 b4 46 00,实际上就成了0x0046b438。彩色表/调色板(color table)是单色、16色和256色图像文件所特有的,相对应的调色板大小是2、16和256,调色板以4字节为单位,每4个字节存放一个颜色值,图像 的数据是指向调色板的索引。
名称 | 占用空间 | 内容 | 实际数据 |
---|---|---|---|
biSize | 4字节 | 位图信息头的大小,总为40 | 0x28(40) |
biWidth | 4字节 | 位图的宽度,单位是像素 | 0x400(1024) |
biHeight | 4字节 | 位图的高度,单位是像素 | 0x300(768) |
biPlanes | 2字节 | 目标绘图设备包含的层数,固定值1 | 1 |
biBitCount | 2字节 | 每个像素的位数1-黑白图,4-16色,8-256色,24-真彩色 | 0x10(16) |
biCompression | 4字节 | 压缩方式,BI_RGB(0)为不压缩 | 0 |
biSizeImage | 4字节 | 位图全部像素占用的字节数,BI_RGB时可设为0 | 0x018000 |
biXPelsPerMeter | 4字节 | 水平分辨率(像素/米) | 0x0b13 |
biYPelsPerMeter | 4字节 | 垂直分辨率(像素/米) | 0x0b13 |
biClrUsed | 4字节 | 位图使用的颜色数如果为0,则颜色数为2的biBitCount次方 | 0 |
biClrImportant | 4字节 | 重要的颜色数,0代表所有颜色都重要 | 0 |
import numpy as np import os from PIL import Image import matplotlib.pyplot as plt import matplotlib as mpl from pprint import pprint def restore1(sigma, u, v, K): # 奇异值、左特征向量、右特征向量 m = len(u) n = len(v[0]) a = np.zeros((m, n)) for k in range(K): uk = u[:, k].reshape(m, 1) vk = v[k].reshape(1, n) a += sigma[k] * np.dot(uk, vk) a[a < 0] = 0 a[a > 255] = 255 # a = a.clip(0, 255) return np.rint(a).astype('uint8') def restore2(sigma, u, v, K): # 奇异值、左特征向量、右特征向量 m = len(u) n = len(v[0]) a = np.zeros((m, n)) for k in range(K+1): for i in range(m): a[i] += sigma[k] * u[i][k] * v[k] a[a < 0] = 0 a[a > 255] = 255 return np.rint(a).astype('uint8') if __name__ == "__main__": A = Image.open("C:\\Users\\Leon_D_Alan\\OneDrive\图片\\ps专用图片副本\\碧翠丝.png", 'r') print(A) output_path = r'C:\\Users\\Leon_D_Alan\\OneDrive\图片\\ps专用图片副本\\SVD_Output' if not os.path.exists(output_path): os.mkdir(output_path) a = np.array(A) print(a.shape) K = 50 u_r, sigma_r, v_r = np.linalg.svd(a[:, :, 0]) u_g, sigma_g, v_g = np.linalg.svd(a[:, :, 1]) u_b, sigma_b, v_b = np.linalg.svd(a[:, :, 2]) plt.figure(figsize=(11, 9), facecolor='w') mpl.rcParams['font.sans-serif'] = ['simHei'] mpl.rcParams['axes.unicode_minus'] = False for k in range(1, K+1): print(k) R = restore1(sigma_r, u_r, v_r, k) G = restore1(sigma_g, u_g, v_g, k) B = restore1(sigma_b, u_b, v_b, k) I = np.stack((R, G, B), axis=2) Image.fromarray(I).save('%s\\svd_%d.png' % (output_path, k)) if k <= 12: plt.subplot(3, 4, k) plt.imshow(I) plt.axis('off') plt.title('奇异值个数:%d' % k) plt.suptitle('SVD与图像分解', fontsize=20) plt.tight_layout() # plt.subplots_adjust(top=0.9) plt.show()
当奇异值越少,图片越模糊。
import cv2 import numpy as np def stackImages(scale, imgArray): """ 将多张图像压入同一个窗口显示 :param scale:float类型,输出图像显示百分比,控制缩放比例,0.5=图像分辨率缩小一半 :param imgArray:元组嵌套列表,需要排列的图像矩阵 :return:输出图像 """ rows = len(imgArray) cols = len(imgArray[0]) rowsAvailable = isinstance(imgArray[0], list) width = imgArray[0][0].shape[1] height = imgArray[0][0].shape[0] if rowsAvailable: for x in range(0, rows): for y in range(0, cols): if imgArray[x][y].shape[:2] == imgArray[0][0].shape[:2]: imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale) else: imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale) if len(imgArray[x][y].shape) == 2: imgArray[x][y] = cv2.cvtColor(imgArray[x][y], cv2.COLOR_GRAY2BGR) imageBlank = np.zeros((height, width, 3), np.uint8) hor = [imageBlank] * rows hor_con = [imageBlank] * rows for x in range(0, rows): hor[x] = np.hstack(imgArray[x]) ver = np.vstack(hor) else: for x in range(0, rows): if imgArray[x].shape[:2] == imgArray[0].shape[:2]: imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale) else: imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None, scale, scale) if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR) hor = np.hstack(imgArray) ver = hor return ver #读取图片 src = cv2.imread("1.png") img = src.copy() #灰度 img_1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #二值化 ret, img_2 = cv2.threshold(img_1, 127, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) #腐蚀 kernel = np.ones((20, 20), int) img_3 = cv2.erode(img_2, kernel, iterations=1) #膨胀 kernel = np.ones((3, 3), int) img_4 = cv2.dilate(img_3, kernel, iterations=1) #找到硬币中心 contours, hierarchy = cv2.findContours(img_4, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2:] #标识硬币 cv2.drawContours(img, contours, -1, (0, 0, 255), 5) #显示图片 cv2.putText(img, "count:{}".format(len(contours)), (0, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255, 0, 0), 3) cv2.putText(src, "src", (0, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255, 0, 0), 3) cv2.putText(img_1, "gray", (0, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255, 0, 0), 3) cv2.putText(img_2, "thresh", (0, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255, 0, 0), 3) cv2.putText(img_3, "erode", (0, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255, 0, 0), 3) cv2.putText(img_4, "dilate", (0, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255, 0, 0), 3) imgStack = stackImages(1, ([src, img_1, img_2], [img_3, img_4, img])) cv2.imshow("imgStack", imgStack) cv2.waitKey(0)
import cv2 import numpy as np def stackImages(scale, imgArray): """ 将多张图像压入同一个窗口显示 :param scale:float类型,输出图像显示百分比,控制缩放比例,0.5=图像分辨率缩小一半 :param imgArray:元组嵌套列表,需要排列的图像矩阵 :return:输出图像 """ rows = len(imgArray) cols = len(imgArray[0]) rowsAvailable = isinstance(imgArray[0], list) width = imgArray[0][0].shape[1] height = imgArray[0][0].shape[0] if rowsAvailable: for x in range(0, rows): for y in range(0, cols): if imgArray[x][y].shape[:2] == imgArray[0][0].shape[:2]: imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale) else: imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale) if len(imgArray[x][y].shape) == 2: imgArray[x][y] = cv2.cvtColor(imgArray[x][y], cv2.COLOR_GRAY2BGR) imageBlank = np.zeros((height, width, 3), np.uint8) hor = [imageBlank] * rows hor_con = [imageBlank] * rows for x in range(0, rows): hor[x] = np.hstack(imgArray[x]) ver = np.vstack(hor) else: for x in range(0, rows): if imgArray[x].shape[:2] == imgArray[0].shape[:2]: imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale) else: imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None, scale, scale) if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR) hor = np.hstack(imgArray) ver = hor return ver #读取图片 src = cv2.imread("1.png") img = src.copy() #灰度 img_1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #二值化 ret, img_2 = cv2.threshold(img_1, 127, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) #腐蚀 kernel = np.ones((20, 20), int) img_3 = cv2.erode(img_2, kernel, iterations=1) #膨胀 kernel = np.ones((3, 3), int) img_4 = cv2.dilate(img_3, kernel, iterations=1) #找到硬币中心 contours, hierarchy = cv2.findContours(img_4, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2:] #标识硬币 cv2.drawContours(img, contours, -1, (0, 0, 255), 5) #显示图片 cv2.putText(img, "count:{}".format(len(contours)), (0, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255, 0, 0), 3) cv2.putText(src, "src", (0, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255, 0, 0), 3) cv2.putText(img_1, "gray", (0, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255, 0, 0), 3) cv2.putText(img_2, "thresh", (0, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 0), 3) cv2.putText(img_3, "erode", (0, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 0), 3) cv2.putText(img_4, "dilate", (0, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 0), 3) imgStack = stackImages(1, ([src, img_1, img_2], [img_3, img_4, img])) cv2.imshow("imgStack", imgStack) cv2.waitKey(0)
pip install imutils pip install pyzbar
import cv2 import numpy as np import imutils from pyzbar import pyzbar def stackImages(scale, imgArray): """ 将多张图像压入同一个窗口显示 :param scale:float类型,输出图像显示百分比,控制缩放比例,0.5=图像分辨率缩小一半 :param imgArray:元组嵌套列表,需要排列的图像矩阵 :return:输出图像 """ rows = len(imgArray) cols = len(imgArray[0]) rowsAvailable = isinstance(imgArray[0], list) width = imgArray[0][0].shape[1] height = imgArray[0][0].shape[0] if rowsAvailable: for x in range(0, rows): for y in range(0, cols): if imgArray[x][y].shape[:2] == imgArray[0][0].shape[:2]: imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale) else: imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale) if len(imgArray[x][y].shape) == 2: imgArray[x][y] = cv2.cvtColor(imgArray[x][y], cv2.COLOR_GRAY2BGR) imageBlank = np.zeros((height, width, 3), np.uint8) hor = [imageBlank] * rows hor_con = [imageBlank] * rows for x in range(0, rows): hor[x] = np.hstack(imgArray[x]) ver = np.vstack(hor) else: for x in range(0, rows): if imgArray[x].shape[:2] == imgArray[0].shape[:2]: imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale) else: imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None, scale, scale) if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR) hor = np.hstack(imgArray) ver = hor return ver #读取图片 src = cv2.imread("C:\\Users\\28205\\Documents\\Tencent Files\\2820535964\\FileRecv\\txm.jpg") img = src.copy() #灰度 img_1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #高斯滤波 img_2 = cv2.GaussianBlur(img_1, (5, 5), 1) #Sobel算子 sobel_x = cv2.Sobel(img_2, cv2.CV_64F, 1, 0, ksize=3) sobel_y = cv2.Sobel(img_2, cv2.CV_64F, 0, 1, ksize=3) sobel_x = cv2.convertScaleAbs(sobel_x) sobel_y = cv2.convertScaleAbs(sobel_y) img_3 = cv2.addWeighted(sobel_x, 0.5, sobel_y, 0.5, 0) #均值方波 img_4 = cv2.blur(img_3, (5, 5)) #二值化 ret, img_5 = cv2.threshold(img_4, 127, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) #闭运算 kernel = np.ones((100, 100), int) img_6 = cv2.morphologyEx(img_5, cv2.MORPH_CLOSE, kernel) #开运算 kernel = np.ones((200, 200), int) img_7 = cv2.morphologyEx(img_6, cv2.MORPH_OPEN, kernel) #绘制条形码区域 contours = cv2.findContours(img_7, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) contours = imutils.grab_contours(contours) c = sorted(contours, key = cv2.contourArea, reverse = True)[0] rect = cv2.minAreaRect(c) box = cv2.cv.BoxPoints(rect) if imutils.is_cv2() else cv2.boxPoints(rect) box = np.int0(box) cv2.drawContours(img, [box], -1, (0,255,0), 20) #显示图片信息 cv2.putText(img, "results", (200, 200), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255, 0, 0), 3) cv2.putText(img_1, "gray", (200, 200), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 0), 3) cv2.putText(img_2, "GaussianBlur",(200, 200), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 0), 3) cv2.putText(img_3, "Sobel", (200, 200), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255, 0, 0), 3) cv2.putText(img_4, "blur", (200, 200), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255, 0, 0), 3) cv2.putText(img_5, "threshold", (200, 200), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255, 0, 0), 3) cv2.putText(img_6, "close", (200, 200), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 0), 3) cv2.putText(img_7, "open", (200, 200), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 0), 3) #输出条形码 barcodes = pyzbar.decode(src) for barcode in barcodes: barcodeData = barcode.data.decode("utf-8") cv2.putText(img, barcodeData, (200, 600), cv2.FONT_HERSHEY_SIMPLEX, 5.0, (0, 255, 0), 30) #显示所有图片 imgStack = stackImages(0.8, ([img_1, img_2],[img_3,img_4],[img_5,img_6],[img_7,img])) cv2.imshow("imgStack", imgStack) cv2.waitKey(0)
在检测图中细胞个数时,效果没有检测硬币那么好,这与图片中某些细胞颜色较浅,转换为灰度图片后,与周围颜色分辨不明显有关。条形码的识别也不是很精准。
https://blog.csdn.net/csdn66_2016/article/details/82850695
https://blog.csdn.net/qq_41881259/article/details/106441768
https://blog.csdn.net/qq_45659777/article/details/121698713