翻拍图像检测(即拍摄屏幕的照片)功能实现思路

Claude Sonnet 4

根据搜索结果和翻拍图像的特征,我来为你提供识别翻拍照片的思路和Python代码实现。

识别思路

翻拍照片(拍摄屏幕的照片)通常具有以下可识别特征:

  1. 摩尔纹检测 - 相机传感器与屏幕像素栅格的干涉模式
  2. 频域分析 - 屏幕刷新频率在频谱中的特征
  3. 亮度均匀性 - 屏幕边缘通常较暗,中心较亮
  4. 色彩分布异常 - 屏幕显示的色彩特征
  5. 边缘检测 - 可能存在屏幕边框
  6. 噪声模式分析 - 电子噪声vs自然光学噪声

Python代码实现

import cv2
import numpy as np
import matplotlib.pyplot as plt
from scipy import ndimage
from sklearn.ensemble import RandomForestClassifier
from skimage import feature, filters, measure
import warnings
warnings.filterwarnings('ignore')
class RecaptureDetector:
    def __init__(self):
        """初始化翻拍图像检测器
        创建随机森林分类器(100棵树,固定随机种子)
        """
        self.classifier = RandomForestClassifier(n_estimators=100, random_state=42)
        
    def extract_moire_features(self, image):
        """提取摩尔纹特征(检测周期性图案)
        输入:
            image: BGR格式的原始图像 (numpy array)
        输出:
            moire_scores: 数组,包含不同角度和频率的Gabor滤波器响应标准差
                (36个特征值:12个角度×3个频率)
        功能:
            1. 将图像转为灰度图
            2. 使用Gabor滤波器在12个角度(0°-150°,步长30°)和3个频率(0.1,0.2,0.3)上检测
            3. 对每个滤波器输出计算标准差作为特征
            4. 返回所有标准差组成的数组
        """
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        
        # 使用不同尺度的Gabor滤波器检测周期性模式
        moire_scores = []
        for theta in range(0, 180, 30):  # 不同角度
            for frequency in [0.1, 0.2, 0.3]:  # 不同频率
                kernel = cv2.getGaborKernel((21, 21), 3, np.radians(theta), 
                                          2*np.pi*frequency, 0.5, 0, ktype=cv2.CV_32F)
                filtered = cv2.filter2D(gray, cv2.CV_8UC3, kernel)
                moire_scores.append(np.std(filtered))
        
        return np.array(moire_scores)
    
    def extract_frequency_features(self, image):
        """提取频域特征(分析图像频率分布)
        输入:
            image: BGR格式的原始图像 (numpy array)
        输出:
            freq_features: 数组,包含20个频率区间内的平均能量
                (20个特征值:从1到20的频率区间)
        功能:
            1. 将图像转为灰度图
            2. 计算2D傅里叶变换并移频
            3. 构建径向距离矩阵
            4. 计算每个频率环(半径1-20)内的平均能量
            5. 返回能量值组成的数组
        """
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        
        # FFT变换
        f_transform = np.fft.fft2(gray)
        f_shift = np.fft.fftshift(f_transform)
        magnitude_spectrum = np.abs(f_shift)
        
        # 计算径向功率谱
        h, w = magnitude_spectrum.shape
        center = (h//2, w//2)
        
        # 创建径向距离矩阵
        y, x = np.ogrid[:h, :w]
        r = np.sqrt((x - center[1])**2 + (y - center[0])**2)
        
        # 计算不同频率的能量
        freq_features = []
        for i in range(1, 20):
            mask = (r >= i) & (r < i+1)
            if np.sum(mask) > 0:
                freq_features.append(np.mean(magnitude_spectrum[mask]))
            else:
                freq_features.append(0)
                
        return np.array(freq_features)
    
    def extract_brightness_uniformity(self, image):
        """提取亮度均匀性特征(分析亮度分布)
        输入:
            image: BGR格式的原始图像 (numpy array)
        输出:
            brightness_features: 包含3个特征的数组
                [中心亮度/边缘平均亮度比, 边缘亮度方差, 中心区域平均亮度]
        功能:
            1. 将图像转为灰度图
            2. 分割图像为中心区域和四个边缘区域
            3. 计算中心区域平均亮度和边缘区域平均亮度
            4. 计算中心与边缘的亮度比例
            5. 计算边缘亮度的方差
            6. 返回特征数组
        """
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        h, w = gray.shape
        
        # 分析不同区域的亮度
        center_region = gray[h//4:3*h//4, w//4:3*w//4]
        edge_regions = [
            gray[:h//4, :],      # 顶部
            gray[3*h//4:, :],    # 底部
            gray[:, :w//4],      # 左侧
            gray[:, 3*w//4:]     # 右侧
        ]
        
        center_brightness = np.mean(center_region)
        edge_brightness = [np.mean(region) for region in edge_regions]
        
        # 计算中心与边缘的亮度差异
        brightness_ratio = center_brightness / (np.mean(edge_brightness) + 1e-6)
        brightness_variance = np.var(edge_brightness)
        
        return np.array([brightness_ratio, brightness_variance, center_brightness])
    
    def extract_color_features(self, image):
        """提取色彩特征(分析颜色分布)
        输入:
            image: BGR格式的原始图像 (numpy array)
        输出:
            color_features: 包含24个特征的数组
                [HSV: H均值/标准差/25%分位数/75%分位数 × 3, LAB: L均值/标准差 × 3]
        功能:
            1. 将图像转为HSV和LAB色彩空间
            2. 对每个通道计算4个统计特征(均值、标准差、25%分位数、75%分位数)
            3. 对HSV的3个通道和LAB的3个通道分别提取
            4. 返回所有特征组成的数组
        """
        # 转换到不同色彩空间
        hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
        lab = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)
        
        # HSV统计特征
        hsv_features = []
        for i in range(3):
            hsv_features.extend([
                np.mean(hsv[:,:,i]),
                np.std(hsv[:,:,i]),
                np.percentile(hsv[:,:,i], 25),
                np.percentile(hsv[:,:,i], 75)
            ])
        
        # LAB色彩空间特征
        lab_features = []
        for i in range(3):
            lab_features.extend([
                np.mean(lab[:,:,i]),
                np.std(lab[:,:,i])
            ])
            
        return np.array(hsv_features + lab_features)
    
    def extract_edge_features(self, image):
        """提取边缘特征(检测屏幕边框)
        输入:
            image: BGR格式的原始图像 (numpy array)
        输出:
            edge_features: 包含5个特征的数组
                [检测到的直线总数, 水平线数量, 垂直线数量, 边缘密度]
        功能:
            1. 将图像转为灰度图
            2. 应用Canny边缘检测
            3. 使用霍夫变换检测直线
            4. 统计水平线和垂直线数量
            5. 计算边缘像素占总像素的比例
            6. 返回特征数组
        """
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        
        # Canny边缘检测
        edges = cv2.Canny(gray, 50, 150)
        
        # 检测直线(可能的屏幕边框)
        lines = cv2.HoughLines(edges, 1, np.pi/180, threshold=100)
        
        if lines is not None:
            # 统计水平和垂直线条
            horizontal_lines = 0
            vertical_lines = 0
            
            for rho, theta in lines[:, 0]:
                if abs(theta) < np.pi/6 or abs(theta - np.pi) < np.pi/6:  # 水平线
                    horizontal_lines += 1
                elif abs(theta - np.pi/2) < np.pi/6:  # 垂直线
                    vertical_lines += 1
            
            edge_features = [len(lines), horizontal_lines, vertical_lines]
        else:
            edge_features = [0, 0, 0]
            
        # 边缘密度
        edge_density = np.sum(edges) / (edges.shape[0] * edges.shape[1])
        edge_features.append(edge_density)
        
        return np.array(edge_features)
    
    def extract_noise_features(self, image):
        """提取噪声特征(分析图像噪声模式)
        输入:
            image: BGR格式的原始图像 (numpy array)
        输出:
            noise_features: 包含8个特征的数组
                [噪声标准差, 噪声绝对均值, 95%分位数, 噪声方差, 局部方差均值, 局部方差标准差]
        功能:
            1. 将图像转为灰度图并转为浮点型
            2. 用高斯滤波估计噪声(原图-平滑图)
            3. 计算噪声的统计特征
            4. 用局部均值滤波计算局部方差
            5. 返回噪声特征数组
        """
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY).astype(np.float32)
        
        # 使用高斯滤波器估计噪声
        blurred = cv2.GaussianBlur(gray, (5, 5), 1.0)
        noise = gray - blurred
        
        # 噪声统计特征
        noise_features = [
            np.std(noise),
            np.mean(np.abs(noise)),
            np.percentile(np.abs(noise), 95),
            np.var(noise)
        ]
        
        # 局部方差分析
        kernel = np.ones((5, 5), np.float32) / 25
        local_mean = cv2.filter2D(gray, -1, kernel)
        local_variance = cv2.filter2D((gray - local_mean)**2, -1, kernel)
        
        noise_features.extend([
            np.mean(local_variance),
            np.std(local_variance)
        ])
        
        return np.array(noise_features)
    
    def extract_all_features(self, image):
         """提取所有特征(整合所有特征提取器)
        输入:
            image: BGR格式的原始图像 (numpy array)
        输出:
            features: 包含所有特征的数组
                (36+20+3+24+5+8 = 96个特征)
        功能:
            1. 缩放图像到最大边800像素以内(加速处理)
            2. 依次调用所有特征提取函数
            3. 将所有特征拼接成一个长数组
            4. 异常处理:特征提取失败时返回None
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值