luoyutianyang commited on
Commit
f81c171
·
verified ·
1 Parent(s): e12095e

Update egg-api.js

Browse files
Files changed (1) hide show
  1. egg-api.js +80 -54
egg-api.js CHANGED
@@ -16,67 +16,93 @@ if (!fs.existsSync(outputDir)) {
16
  }
17
 
18
  // 并行处理图片下载和处理
19
- async function processImage(url, inputImagePath, outputImagePath, classifiersFolder, replacementImagePath) {
20
- try {
21
- // 下载并转换输入图片
22
- const response = await axios.get(url, { responseType: 'arraybuffer' });
23
- await sharp(response.data).toFile(inputImagePath);
24
-
25
- // 图片下载和转换完成后进行人脸替换
26
- await replaceFaces(inputImagePath, outputImagePath, classifiersFolder, replacementImagePath);
27
-
28
- console.log('Image processed successfully.');
29
- } catch (error) {
30
- console.error('Error processing image:', error);
31
- throw error;
32
- }
 
 
33
  }
34
 
35
  // 加载所有分类器
36
- async function loadClassifiersFromFolder(folderPath) {
37
  const classifiers = [];
38
- const files = fs.readdirSync(folderPath);
39
- for (const file of files) {
40
- const filePath = path.join(folderPath, file);
41
- const classifier = new cv.CascadeClassifier(filePath);
42
- classifiers.push(classifier);
43
- }
44
- return classifiers;
 
 
 
 
 
 
 
 
 
45
  }
46
 
47
  // 人脸替换函数
48
- async function replaceFaces(inputImagePath, outputImagePath, classifiersFolder, replacementImagePath) {
49
- const img = cv.imread(inputImagePath);
50
- const classifiers = await loadClassifiersFromFolder(classifiersFolder);
51
- const replacementFace = await Jimp.read(replacementImagePath);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
- const grayImg = img.bgrToGray();
54
- const allFaces = [];
55
- classifiers.forEach(classifier => {
56
- const faces = classifier.detectMultiScale(grayImg).objects;
57
- allFaces.push(...faces);
58
- });
 
 
 
 
 
 
 
 
59
 
60
- allFaces.forEach(faceRect => {
61
- const resizedReplacementFace = replacementFace.resize(faceRect.width, faceRect.height);
62
- const faceRegion = img.getRegion(faceRect);
63
- const replacementBuffer = resizedReplacementFace.bitmap.data;
64
- for (let y = 0; y < faceRect.height; y++) {
65
- for (let x = 0; x < faceRect.width; x++) {
66
- const idx = (y * faceRect.width + x) << 2;
67
- const [r, g, b, a] = replacementBuffer.slice(idx, idx + 4);
68
- if (a > 0) {
69
- faceRegion.set(y, x, new cv.Vec3(b, g, r));
70
- }
71
- }
72
- }
73
  });
74
-
75
- cv.imwrite(outputImagePath, img);
76
  }
77
 
78
  // Express接口
79
- app.get('/process-image', async (req, res) => {
80
  const { imageUrl } = req.query;
81
 
82
  if (!imageUrl) {
@@ -88,13 +114,13 @@ app.get('/process-image', async (req, res) => {
88
  const replacementImagePath = './replacement_face.png';
89
  const classifiersFolder = './classifiers';
90
 
91
- try {
92
- await processImage(imageUrl, inputImagePath, outputImagePath, classifiersFolder, replacementImagePath);
 
 
 
93
  res.sendFile(outputImagePath, { root: '.' });
94
- } catch (error) {
95
- console.error('Error processing image:', error);
96
- res.status(500).send('Error processing image');
97
- }
98
  });
99
 
100
  app.listen(port, () => {
 
16
  }
17
 
18
  // 并行处理图片下载和处理
19
+ function processImage(url, inputImagePath, outputImagePath, classifiersFolder, replacementImagePath, callback) {
20
+ axios.get(url, { responseType: 'arraybuffer' })
21
+ .then(response => {
22
+ return sharp(response.data).toFile(inputImagePath);
23
+ })
24
+ .then(() => {
25
+ return replaceFaces(inputImagePath, outputImagePath, classifiersFolder, replacementImagePath);
26
+ })
27
+ .then(() => {
28
+ console.log('Image processed successfully.');
29
+ callback(null);
30
+ })
31
+ .catch(error => {
32
+ console.error('Error processing image:', error);
33
+ callback(error);
34
+ });
35
  }
36
 
37
  // 加载所有分类器
38
+ function loadClassifiersFromFolder(folderPath, callback) {
39
  const classifiers = [];
40
+ fs.readdir(folderPath, (err, files) => {
41
+ if (err) {
42
+ callback(err);
43
+ return;
44
+ }
45
+ let completed = 0;
46
+ files.forEach(file => {
47
+ const filePath = path.join(folderPath, file);
48
+ const classifier = new cv.CascadeClassifier(filePath);
49
+ classifiers.push(classifier);
50
+ completed++;
51
+ if (completed === files.length) {
52
+ callback(null, classifiers);
53
+ }
54
+ });
55
+ });
56
  }
57
 
58
  // 人脸替换函数
59
+ function replaceFaces(inputImagePath, outputImagePath, classifiersFolder, replacementImagePath, callback) {
60
+ cv.imreadAsync(inputImagePath, (err, img) => {
61
+ if (err) {
62
+ callback(err);
63
+ return;
64
+ }
65
+ loadClassifiersFromFolder(classifiersFolder, (err, classifiers) => {
66
+ if (err) {
67
+ callback(err);
68
+ return;
69
+ }
70
+ Jimp.read(replacementImagePath, (err, replacementFace) => {
71
+ if (err) {
72
+ callback(err);
73
+ return;
74
+ }
75
+ const grayImg = img.bgrToGray();
76
+ const allFaces = [];
77
+ classifiers.forEach(classifier => {
78
+ const faces = classifier.detectMultiScale(grayImg).objects;
79
+ allFaces.push(...faces);
80
+ });
81
 
82
+ allFaces.forEach(faceRect => {
83
+ const resizedReplacementFace = replacementFace.resize(faceRect.width, faceRect.height);
84
+ const faceRegion = img.getRegion(faceRect);
85
+ const replacementBuffer = resizedReplacementFace.bitmap.data;
86
+ for (let y = 0; y < faceRect.height; y++) {
87
+ for (let x = 0; x < faceRect.width; x++) {
88
+ const idx = (y * faceRect.width + x) << 2;
89
+ const [r, g, b, a] = replacementBuffer.slice(idx, idx + 4);
90
+ if (a > 0) {
91
+ faceRegion.set(y, x, new cv.Vec3(b, g, r));
92
+ }
93
+ }
94
+ }
95
+ });
96
 
97
+ cv.imwrite(outputImagePath, img);
98
+ callback(null);
99
+ });
100
+ });
 
 
 
 
 
 
 
 
 
101
  });
 
 
102
  }
103
 
104
  // Express接口
105
+ app.get('/process-image', (req, res) => {
106
  const { imageUrl } = req.query;
107
 
108
  if (!imageUrl) {
 
114
  const replacementImagePath = './replacement_face.png';
115
  const classifiersFolder = './classifiers';
116
 
117
+ processImage(imageUrl, inputImagePath, outputImagePath, classifiersFolder, replacementImagePath, (err) => {
118
+ if (err) {
119
+ console.error('Error processing image:', err);
120
+ return res.status(500).send('Error processing image');
121
+ }
122
  res.sendFile(outputImagePath, { root: '.' });
123
+ });
 
 
 
124
  });
125
 
126
  app.listen(port, () => {