拉普拉斯图像融合,基于sobel算子的边缘检测,PCA人脸识别,SIFT图像配准,分形维数计算,数字图像水印,霍夫变换做直线检测,人脸纹理识别,伪彩色增强,图像增强,图像分割,特征提取,字符分割,各种GUI,等等各种跟图像处理有关的程序。

边缘检测这招,用Sobel算子最顺手。直接上OpenCV全家桶:

import cv2
img = cv2.imread('test.jpg', 0)
sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
edges = cv2.addWeighted(sobelx, 0.5, sobely, 0.5, 0)

注意这里cv2.CV_64F参数是关键,因为Sobel计算会有负数,用uint8会丢失负值导致边缘断裂。想更锐利可以试试Scharr算子,效果类似但梯度计算更敏感。

分形维数计算看着玄乎,实际就是个盒计数法的事:

def calculate_fractal_dimension(image, box_sizes=range(1, 50)):
    counts = []
    for size in box_sizes:
        grid = image.shape[0] // size
        non_empty = 0
        for i in range(grid):
            for j in range(grid):
                if np.any(image[i*size:(i+1)*size, j*size:(j+1)*size]):
                    non_empty +=1
        counts.append(non_empty)
    coeffs = np.polyfit(np.log(1/np.array(box_sizes)), np.log(counts), 1)
    return coeffs[0]

这函数把图像分成不同大小的网格统计覆盖区域,最后用双对数坐标做线性回归。实际用的时候记得先把图像二值化,分形维数越接近2说明纹理越复杂。

霍夫直线检测经常被吐槽调参难,试试这个参数组合:

edges = cv2.Canny(img, 50, 150)
lines = cv2.HoughLinesP(edges, 1, np.pi/180, threshold=80, minLineLength=50, maxLineGap=10)

重点在Canny边缘的质量直接影响结果。maxLineGap参数控制允许连接的最大断裂距离,遇到虚线场景可以适当调大。画线时记得用深拷贝,不然原图会被污染。

伪彩色增强适合给灰度图整点视觉冲击:

lut = np.zeros((256, 3), dtype=np.uint8)
lut[:,0] = np.clip(128 + 2* np.arange(256), 0, 255)  # 红色通道
lut[:,1] = np.abs(128 - np.arange(256)) * 2         # 绿色通道
color_img = cv2.LUT(gray_img, lut)

这里手动构建颜色查找表,红色分量做线性增强,绿色分量搞个V型分布。LUT映射比逐像素操作快十倍不止,处理视频流时尤其明显。

拉普拉斯图像融合,基于sobel算子的边缘检测,PCA人脸识别,SIFT图像配准,分形维数计算,数字图像水印,霍夫变换做直线检测,人脸纹理识别,伪彩色增强,图像增强,图像分割,特征提取,字符分割,各种GUI,等等各种跟图像处理有关的程序。

人脸识别里的PCA降维别被名字吓到,sklearn分分钟搞定:

from sklearn.decomposition import PCA
pca = PCA(n_components=50)
faces_flat = face_images.reshape(len(face_images), -1)
reduced = pca.fit_transform(faces_flat)
reconstructed = pca.inverse_transform(reduced)

注意输入数据需要展平为二维矩阵(样本数×像素数)。重建图像时记得clip到0-255,否则可能出现诡异色块。n_components一般取总方差95%对应的维度数。

图像配准用SIFT虽然被专利搞过,但效果确实顶:

sift = cv2.SIFT_create()
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)
good = [m for m,n in matches if m.distance < 0.75*n.distance]

匹配时用knnMatch比普通match多了比率过滤,能筛掉大量误匹配。想更精准可以加RANSAC计算单应矩阵,但实时性会下降。

GUI开发别死磕Qt,试试cv2自带的highgui:

cv2.namedWindow('adjust')
cv2.createTrackbar('threshold', 'adjust', 127, 255, callback)
while True:
    thresh = cv2.getTrackbarPos('threshold', 'adjust')
    _, binary = cv2.threshold(img, thresh, 255, cv2.THRESH_BINARY)
    cv2.imshow('adjust', binary)
    if cv2.waitKey(1) == 27:
        break

虽然界面简陋,但胜在零依赖。回调函数里别做耗时操作,否则拖动卡成PPT。记得窗口名字要统一,不然trackbar会挂到别的窗口上。

这些代码块就像乐高积木,拆开重组能搭出各种有意思的应用。比如用分形维数做纹理分类,霍夫直线辅助文档校正,伪彩色增强结合PCA做特征可视化。图像处理的乐趣就在于,永远有新的组合方式等着被挖掘。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐