基于OpenCv做照片分析应用一(Java)

前言

这里今天遇到的场景是前端打印一个pdf文件,右上角里面嵌入一个照片。照片嘛,肯定因为个体差异,机器拍出来的位置肯定是可能有瑕疵,需要人为干预剪裁,这样那里迁入的才好看。虽然pdf是设备上自己组装的,但是因为某些原因,这里需要后端吃亏处理下。


一、具体情况

  • 照片在七牛云按流量上传、下载双向收费。
  • 接口是纯数据接口,返回的数据是pdf上的数据,照片是七牛云的url。

二、分析

因为嵌入的图片主要是要有人脸,且不能比例不能压缩,不然图像变形,审核业务要是遇到较真的人,那狠难受。

这里跟设备端写WPF的沟通,跟我们后端梳理业务接口后,因为照片文件大小、存储机制、网络带宽等问题,确定这块工作在设备端WPF处理最好,但是很多时候有点事与愿违。我大java大度点,退一步,处理好坐标,在接口里返回,WPF端自己按照坐标剪切。

具体代码我就不再重复了,可以见上一篇分享的基于OpenCv做照片分析

这里就实现继续再上次的测试类里定义一个方法,在具体实现体现逻辑吧。

三、思路

  • 定位到照片的人脸
  • 根据基于openVC检测到的人脸的第一个点位,做计算
  • 取4个点位(截取的具体点位)

1.PhotoInfo

代码如下(示例):

java 复制代码
import lombok.Data;

import java.util.List;

/**
 * @author zwmac
 */
@Data
public class PhotoInfo {

    private List<PhotoCropPoint>  photoCropPointList;
}

2.PhotoCropPoint

java 复制代码
import lombok.Data;

/**
 * @author zwmac
 */
@Data
public class PhotoCropPoint {

    private Integer xPoint;

    private Integer yPoint;
}

3.IOpenCvService增加方法

java 复制代码
/**
     * 定位并计算指标
     * @param faceFile
     * @return
     */
    List<PhotoCropPoint> analyzeCropPointList(File faceFile,String cascadeName);

4.analyzeCropPointList方法实现

java 复制代码
    @Override
    public List<PhotoCropPoint> analyzeCropPointList(File imageFile, String cascadeName) {
        List<PhotoCropPoint> photoCropPointList = new ArrayList<>();
        //读取检测项图片
        Mat src = Imgcodecs.imread(imageFile.getAbsolutePath());
        if (!src.empty()) {
            //灰度化
            Mat gray = new Mat();
            Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY);

            //加载训练好的检测模型
            CascadeClassifier classifier = OpenCVUtil.getCascade(cascadeName);
            Assert.notNull(classifier, "模型:" + cascadeName + "加载失败");

            //检测检测项
            MatOfRect matOfRect = new MatOfRect();
            classifier.detectMultiScale(gray, matOfRect);

            //判断检测结果
            if (matOfRect.toArray().length != 0) {
                // 5. 打印检测到的矩形框
                Rect[] rects = matOfRect.toArray();
                for (Rect rect : rects) {

                    //int x = rect.x;
                    //int y = rect.y;
                    //int width = rect.width;
                    //int height = rect.height;
                    //-120可调整,这里的依据是人肩宽平均值再45 + 手臂展开预估宽度
                    int x = rect.x - 120;
                    //-60是人脸识别在人头上移高度
                    int y = rect.y - 60;
                    int width = rect.width + 240;
                    //我们这里拍出来的照片是640 * 480的
                    int height = 480 - y;

                    System.out.println("x=" + x + ", y=" + y +
                            ", width=" + width + ", height=" + height);

                    // 在原图上画矩形
                    Imgproc.rectangle(src,
                            new Point(x, y),
                            new Point(x + width, y + height),
                            new Scalar(0, 255, 0), 2);

                    PhotoCropPoint  photoCropPoint = new PhotoCropPoint();
                    photoCropPoint.setXPoint(x);
                    photoCropPoint.setYPoint(y);
                    photoCropPointList.add(photoCropPoint);

                    PhotoCropPoint  photoCropPoint2 = new PhotoCropPoint();
                    photoCropPoint2.setXPoint(x);
                    photoCropPoint2.setYPoint(height);
                    photoCropPointList.add(photoCropPoint2);

                    PhotoCropPoint  photoCropPoint3 = new PhotoCropPoint();
                    photoCropPoint3.setXPoint(x + width);
                    photoCropPoint3.setYPoint(y);
                    photoCropPointList.add(photoCropPoint3);

                    PhotoCropPoint  photoCropPoint4 = new PhotoCropPoint();
                    photoCropPoint4.setXPoint(x + width);
                    photoCropPoint4.setYPoint(height);
                    photoCropPointList.add(photoCropPoint4);

                }

                // 6. 保存结果图
                String resultTime = DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss");
                String resultPath = "/Users/zwmac/Downloads/test/result_" + resultTime + ".jpg";
                Imgcodecs.imwrite(resultPath, src);
                System.out.println("结果已保存: " + resultPath);
            }


        }
        return photoCropPointList;
    }

四、效果


总结

  • 没有弱语种,只有弱人
  • team也很重要
  • 纯粹证明我大java有这个能力,不是我们做不了推脱
相关推荐
luteres14 分钟前
Mybatis+SSM整合笔记
java·开发语言·mybatis
其实防守也摸鱼26 分钟前
推荐一个自动化教育SRC漏洞挖掘系统--AutoHunter
运维·开发语言·人工智能·学习·安全·web安全·自动化
振浩微433射频芯片29 分钟前
从门锁到考勤,VRC522B如何在近场读卡场景中“稳坐C位”?
网络·人工智能·单片机·物联网
码视野31 分钟前
多宠 RFID 颈圈识别与湿粮半导体制冷保鲜分餐喂食器解决方案(软硬件一体化)
大数据·人工智能·python
九硕智慧建筑一体化厂家41 分钟前
智慧建筑高效管控!楼宇自控系统赋能新能源园区智能运维
运维·人工智能·笔记·智慧城市
2601_954526751 小时前
2026 生成式搜索引擎底层技术演进与 GEO优化服务商推荐:大模型检索增强(RAG)管道与语义对齐工程实战
大数据·人工智能·搜索引擎
我有满天星辰2 小时前
Spring AI Prompt 实战:System Prompt、User Prompt 与 PromptTemplate
人工智能·spring·prompt
A15362552 小时前
WMS 仓储管理系统推荐:企业如何选适配的仓储管理系统
大数据·人工智能
学习中.........2 小时前
Transformer 训练资源估算:以 CS336 GPT-2 XL 配置为例
人工智能·python·算法·机器学习·自然语言处理
Setsuna_F_Seiei6 小时前
前端的 AI 学习之路 02 之 Provider 与 Structured Output - 规范化模型输入输出
人工智能·agent·ai编程