I have currently implemented a version of this tutorial:
Real Time AI Face Landmark Detection in 20 Minutes with Tensorflow.JS and React
It demonstrates how to implement the Tensorflow.JS facemesh model, and how to display the mesh using a drawPath function.
The code works as follows:
function App() {
const webcamRef = useRef(null);
const canvasRef = useRef(null);
// Load posenet
const runFacemesh = async () => {
const net = await facemesh.load(facemesh.SupportedPackages.mediapipeFacemesh);
setInterval(() => {
detect(net);
}, 10);
};
const detect = async (net) => {
// check a return on webcam data
if (
typeof webcamRef.current !== "undefined" &&
webcamRef.current !== null &&
webcamRef.current.video.readyState === 4
) {
// Get Video Properties
const video = webcamRef.current.video;
const videoWidth = webcamRef.current.video.videoWidth;
const videoHeight = webcamRef.current.video.videoHeight;
// Set video width
webcamRef.current.video.width = videoWidth;
webcamRef.current.video.height = videoHeight;
// Set canvas width and height
canvasRef.current.width = videoWidth;
canvasRef.current.height = videoHeight;
// feed vid
const face = await net.estimateFaces({input:video});
// console.log(face);
// Get canvas context
const yY = canvasRef.current.getContext("2d");
requestAnimationFrame(()=>{drawMesh(face, ctx)});
}
};
// call function for drawing facemesh
useEffect(()=>{runFacemesh()}, []);
// setup webcam and canvas
return (
<div className="App">
<header className="App-header">
<Webcam
ref={webcamRef}
style={{
position: "absolute",
marginLeft: "auto",
marginRight: "auto",
left: 0,
right: 0,
textAlign: "center",
zindex: 9,
width: 640,
height: 480,
}}
/>
<canvas
ref={canvasRef}
style={{
position: "absolute",
marginLeft: "auto",
marginRight: "auto",
left: 0,
right: 0,
textAlign: "center",
zindex: 9,
width: 640,
height: 480,
}}
/>
</header>
</div>
);
}
export default App;
Above is the main app function that loads the facemesh and detects the model. Within this function I am calling a drawMesh function which takes a face parameter which is defined as the estimated detections called against the video input and a ctx object:
The drawMesh function and path drawing method are defined as follows:
// Triangle drawing method
const drawPath = (ctx, points, closePath) => {
const region = new Path2D();
region.moveTo(points[0][0], points[0][1]);
for (let i = 1; i < points.length; i++) {
const point = points[i];
region.lineTo(point[0], point[1]);
}
if (closePath) {
region.closePath();
}
ctx.strokeStyle = "grey";
ctx.stroke(region);
};
// Drawing Mesh
export const drawMesh = (predictions, ctx) => {
if (predictions.length > 0) {
predictions.forEach((prediction) => {
const keypoints = prediction.scaledMesh;
// Draw Triangles
for (let i = 0; i < TRIANGULATION.length / 3; i++) {
// Get sets of three keypoints for the triangle
const points = [
TRIANGULATION[i * 3],
TRIANGULATION[i * 3 + 1],
TRIANGULATION[i * 3 + 2],
].map((index) => keypoints[index]);
// Draw triangle
drawPath(ctx, points, true);
}
// Draw Dots
for (let i = 0; i < keypoints.length; i++) {
const x = keypoints[i][0];
const y = keypoints[i][1];
ctx.beginPath();
ctx.arc(x, y, 1 /* radius */, 0, 3 * Math.PI);
ctx.fillStyle = "aqua";
ctx.fill();
}
});
}
};
It works by referring points from a triangle array defined here:
export const TRIANGULATION = [
127, 34, 139, 11, 0, 37, 232, 231, 120, 72, 37, 39, 128, 121, 47, 232, 121,
128, 104, 69, 67, 175, 171, 148, 157, 154, 155, 118, 50, 101, 73, 39, 40, 9,
151, 108, 48, 115, 131, 194, 204, 211, 74, 40, 185, 80, 42, 183, 40, 92, 186,
230, 229, 118, 202, 212, 214, 83, 18, 17, 76, 61, 146, 160, 29, 30, 56, 157,
173, 106, 204, 194, 135, 214, 192, 203, 165, 98, 21, 71, 68, 51, 45, 4, 144,
24, 23, 77, 146, 91, 205, 50, 187, 201, 200, 18, 91, 106, 182, 90, 91, 181,
85, 84, 17, 206, 203, 36, 148, 171, 140, 92, 40, 39, 193, 189, 244, 159, 158,
28, 247, 246, 161, 236, 3, 196, 54, 68, 104, 193, 168, 8, 117, 228, 31, 189,
193, 55, 98, 97, 99, 126, 47, 100, 166, 79, 218, 155, 154, 26, 209, 49, 131,
135, 136, 150, 47, 126, 217, 223, 52, 53, 45, 51, 134, 211, 170, 140, 67, 69,
108, 43, 106, 91, 230, 119, 120, 226, 130, 247, 63, 53, 52, 238, 20, 242, 46,
70, 156, 78, 62, 96, 46, 53, 63, 143, 34, 227, 173, 155, 133, 123, 117, 111,
44, 125, 19, 236, 134, 51, 216, 206, 205, 154, 153, 22, 39, 37, 167, 200, 201,
208, 36, 142, 100, 57, 212, 202, 20, 60, 99, 28, 158, 157, 35, 226, 113, 160,
159, 27, 204, 202, 210, 113, 225, 46, 43, 202, 204, 62, 76, 77, 137, 123, 116,
41, 38, 72, 203, 129, 142, 64, 98, 240, 49, 102, 64, 41, 73, 74, 212, 216,
207, 42, 74, 184, 169, 170, 211, 170, 149, 176, 105, 66, 69, 122, 6, 168, 123,
147, 187, 96, 77, 90, 65, 55, 107, 89, 90, 180, 101, 100, 120, 63, 105, 104,
93, 137, 227, 15, 86, 85, 129, 102, 49, 14, 87, 86, 55, 8, 9, 100, 47, 121,
145, 23, 22, 88, 89, 179, 6, 122, 196, 88, 95, 96, 138, 172, 136, 215, 58,
172, 115, 48, 219, 42, 80, 81, 195, 3, 51, 43, 146, 61, 171, 175, 199, 81, 82,
38, 53, 46, 225, 144, 163, 110, 246, 33, 7, 52, 65, 66, 229, 228, 117, 34,
127, 234, 107, 108, 69, 109, 108, 151, 48, 64, 235, 62, 78, 191, 129, 209,
126, 111, 35, 143, 163, 161, 246, 117, 123, 50, 222, 65, 52, 19, 125, 141,
221, 55, 65, 3, 195, 197, 25, 7, 33, 220, 237, 44, 70, 71, 139, 122, 193, 245,
247, 130, 33, 71, 21, 162, 153, 158, 159, 170, 169, 150, 188, 174, 196, 216,
186, 92, 144, 160, 161, 2, 97, 167, 141, 125, 241, 164, 167, 37, 72, 38, 12,
145, 159, 160, 38, 82, 13, 63, 68, 71, 226, 35, 111, 158, 153, 154, 101, 50,
205, 206, 92, 165, 209, 198, 217, 165, 167, 97, 220, 115, 218, 133, 112, 243,
239, 238, 241, 214, 135, 169, 190, 173, 133, 171, 208, 32, 125, 44, 237, 86,
87, 178, 85, 86, 179, 84, 85, 180, 83, 84, 181, 201, 83, 182, 137, 93, 132,
76, 62, 183, 61, 76, 184, 57, 61, 185, 212, 57, 186, 214, 207, 187, 34, 143,
156, 79, 239, 237, 123, 137, 177, 44, 1, 4, 201, 194, 32, 64, 102, 129, 213,
215, 138, 59, 166, 219, 242, 99, 97, 2, 94, 141, 75, 59, 235, 24, 110, 228,
25, 130, 226, 23, 24, 229, 22, 23, 230, 26, 22, 231, 112, 26, 232, 189, 190,
243, 221, 56, 190, 28, 56, 221, 27, 28, 222, 29, 27, 223, 30, 29, 224, 247,
30, 225, 238, 79, 20, 166, 59, 75, 60, 75, 240, 147, 177, 215, 20, 79, 166,
187, 147, 213, 112, 233, 244, 233, 128, 245, 128, 114, 188, 114, 217, 174,
131, 115, 220, 217, 198, 236, 198, 131, 134, 177, 132, 58, 143, 35, 124, 110,
163, 7, 228, 110, 25, 356, 389, 368, 11, 302, 267, 452, 350, 349, 302, 303,
269, 357, 343, 277, 452, 453, 357, 333, 332, 297, 175, 152, 377, 384, 398,
382, 347, 348, 330, 303, 304, 270, 9, 336, 337, 278, 279, 360, 418, 262, 431,
304, 408, 409, 310, 415, 407, 270, 409, 410, 450, 348, 347, 422, 430, 434,
313, 314, 17, 306, 307, 375, 387, 388, 260, 286, 414, 398, 335, 406, 418, 364,
367, 416, 423, 358, 327, 251, 284, 298, 281, 5, 4, 373, 374, 253, 307, 320,
321, 425, 427, 411, 421, 313, 18, 321, 405, 406, 320, 404, 405, 315, 16, 17,
426, 425, 266, 377, 400, 369, 322, 391, 269, 417, 465, 464, 386, 257, 258,
466, 260, 388, 456, 399, 419, 284, 332, 333, 417, 285, 8, 346, 340, 261, 413,
441, 285, 327, 460, 328, 355, 371, 329, 392, 439, 438, 382, 341, 256, 429,
420, 360, 364, 394, 379, 277, 343, 437, 443, 444, 283, 275, 440, 363, 431,
262, 369, 297, 338, 337, 273, 375, 321, 450, 451, 349, 446, 342, 467, 293,
334, 282, 458, 461, 462, 276, 353, 383, 308, 324, 325, 276, 300, 293, 372,
345, 447, 382, 398, 362, 352, 345, 340, 274, 1, 19, 456, 248, 281, 436, 427,
425, 381, 256, 252, 269, 391, 393, 200, 199, 428, 266, 330, 329, 287, 273,
422, 250, 462, 328, 258, 286, 384, 265, 353, 342, 387, 259, 257, 424, 431,
430, 342, 353, 276, 273, 335, 424, 292, 325, 307, 366, 447, 345, 271, 303,
302, 423, 266, 371, 294, 455, 460, 279, 278, 294, 271, 272, 304, 432, 434,
427, 272, 407, 408, 394, 430, 431, 395, 369, 400, 334, 333, 299, 351, 417,
168, 352, 280, 411, 325, 319, 320, 295, 296, 336, 319, 403, 404, 330, 348,
349, 293, 298, 333, 323, 454, 447, 15, 16, 315, 358, 429, 279, 14, 15, 316,
285, 336, 9, 329, 349, 350, 374, 380, 252, 318, 402, 403, 6, 197, 419, 318,
319, 325, 367, 364, 365, 435, 367, 397, 344, 438, 439, 272, 271, 311, 195, 5,
281, 273, 287, 291, 396, 428, 199, 311, 271, 268, 283, 444, 445, 373, 254,
339, 263, 466, 249, 282, 334, 296, 449, 347, 346, 264, 447, 454, 336, 296,
299, 338, 10, 151, 278, 439, 455, 292, 407, 415, 358, 371, 355, 340, 345, 372,
390, 249, 466, 346, 347, 280, 442, 443, 282, 19, 94, 370, 441, 442, 295, 248,
419, 197, 263, 255, 359, 440, 275, 274, 300, 383, 368, 351, 412, 465, 263,
467, 466, 301, 368, 389, 380, 374, 386, 395, 378, 379, 412, 351, 419, 436,
426, 322, 373, 390, 388, 2, 164, 393, 370, 462, 461, 164, 0, 267, 302, 11, 12,
374, 373, 387, 268, 12, 13, 293, 300, 301, 446, 261, 340, 385, 384, 381, 330,
266, 425, 426, 423, 391, 429, 355, 437, 391, 327, 326, 440, 457, 438, 341,
382, 362, 459, 457, 461, 434, 430, 394, 414, 463, 362, 396, 369, 262, 354,
461, 457, 316, 403, 402, 315, 404, 403, 314, 405, 404, 313, 406, 405, 421,
418, 406, 366, 401, 361, 306, 408, 407, 291, 409, 408, 287, 410, 409, 432,
436, 410, 434, 416, 411, 264, 368, 383, 309, 438, 457, 352, 376, 401, 274,
275, 4, 421, 428, 262, 294, 327, 358, 433, 416, 367, 289, 455, 439, 462, 370,
326, 2, 326, 370, 305, 460, 455, 254, 449, 448, 255, 261, 446, 253, 450, 449,
252, 451, 450, 256, 452, 451, 341, 453, 452, 413, 464, 463, 441, 413, 414,
258, 442, 441, 257, 443, 442, 259, 444, 443, 260, 445, 444, 467, 342, 445,
459, 458, 250, 289, 392, 290, 290, 328, 460, 376, 433, 435, 250, 290, 392,
411, 416, 433, 341, 463, 464, 453, 464, 465, 357, 465, 412, 343, 412, 399,
360, 363, 440, 437, 399, 456, 420, 456, 363, 401, 435, 288, 372, 383, 353,
339, 255, 249, 448, 261, 255, 133, 243, 190, 133, 155, 112, 33, 246, 247, 33,
130, 25, 398, 384, 286, 362, 398, 414, 362, 463, 341, 263, 359, 467, 263, 249,
255, 466, 467, 260, 75, 60, 166, 238, 239, 79, 162, 127, 139, 72, 11, 37, 121,
232, 120, 73, 72, 39, 114, 128, 47, 233, 232, 128, 103, 104, 67, 152, 175,
148, 173, 157, 155, 119, 118, 101, 74, 73, 40, 107, 9, 108, 49, 48, 131, 32,
194, 211, 184, 74, 185, 191, 80, 183, 185, 40, 186, 119, 230, 118, 210, 202,
214, 84, 83, 17, 77, 76, 146, 161, 160, 30, 190, 56, 173, 182, 106, 194, 138,
135, 192, 129, 203, 98, 54, 21, 68, 5, 51, 4, 145, 144, 23, 90, 77, 91, 207,
205, 187, 83, 201, 18, 181, 91, 182, 180, 90, 181, 16, 85, 17, 205, 206, 36,
176, 148, 140, 165, 92, 39, 245, 193, 244, 27, 159, 28, 30, 247, 161, 174,
236, 196, 103, 54, 104, 55, 193, 8, 111, 117, 31, 221, 189, 55, 240, 98, 99,
142, 126, 100, 219, 166, 218, 112, 155, 26, 198, 209, 131, 169, 135, 150, 114,
47, 217, 224, 223, 53, 220, 45, 134, 32, 211, 140, 109, 67, 108, 146, 43, 91,
231, 230, 120, 113, 226, 247, 105, 63, 52, 241, 238, 242, 124, 46, 156, 95,
78, 96, 70, 46, 63, 116, 143, 227, 116, 123, 111, 1, 44, 19, 3, 236, 51, 207,
216, 205, 26, 154, 22, 165, 39, 167, 199, 200, 208, 101, 36, 100, 43, 57, 202,
242, 20, 99, 56, 28, 157, 124, 35, 113, 29, 160, 27, 211, 204, 210, 124, 113,
46, 106, 43, 204, 96, 62, 77, 227, 137, 116, 73, 41, 72, 36, 203, 142, 235,
64, 240, 48, 49, 64, 42, 41, 74, 214, 212, 207, 183, 42, 184, 210, 169, 211,
140, 170, 176, 104, 105, 69, 193, 122, 168, 50, 123, 187, 89, 96, 90, 66, 65,
107, 179, 89, 180, 119, 101, 120, 68, 63, 104, 234, 93, 227, 16, 15, 85, 209,
129, 49, 15, 14, 86, 107, 55, 9, 120, 100, 121, 153, 145, 22, 178, 88, 179,
197, 6, 196, 89, 88, 96, 135, 138, 136, 138, 215, 172, 218, 115, 219, 41, 42,
81, 5, 195, 51, 57, 43, 61, 208, 171, 199, 41, 81, 38, 224, 53, 225, 24, 144,
110, 105, 52, 66, 118, 229, 117, 227, 34, 234, 66, 107, 69, 10, 109, 151, 219,
48, 235, 183, 62, 191, 142, 129, 126, 116, 111, 143, 7, 163, 246, 118, 117,
50, 223, 222, 52, 94, 19, 141, 222, 221, 65, 196, 3, 197, 45, 220, 44, 156,
70, 139, 188, 122, 245, 139, 71, 162, 145, 153, 159, 149, 170, 150, 122, 188,
196, 206, 216, 92, 163, 144, 161, 164, 2, 167, 242, 141, 241, 0, 164, 37, 11,
72, 12, 144, 145, 160, 12, 38, 13, 70, 63, 71, 31, 226, 111, 157, 158, 154,
36, 101, 205, 203, 206, 165, 126, 209, 217, 98, 165, 97, 237, 220, 218, 237,
239, 241, 210, 214, 169, 140, 171, 32, 241, 125, 237, 179, 86, 178, 180, 85,
179, 181, 84, 180, 182, 83, 181, 194, 201, 182, 177, 137, 132, 184, 76, 183,
185, 61, 184, 186, 57, 185, 216, 212, 186, 192, 214, 187, 139, 34, 156, 218,
79, 237, 147, 123, 177, 45, 44, 4, 208, 201, 32, 98, 64, 129, 192, 213, 138,
235, 59, 219, 141, 242, 97, 97, 2, 141, 240, 75, 235, 229, 24, 228, 31, 25,
226, 230, 23, 229, 231, 22, 230, 232, 26, 231, 233, 112, 232, 244, 189, 243,
189, 221, 190, 222, 28, 221, 223, 27, 222, 224, 29, 223, 225, 30, 224, 113,
247, 225, 99, 60, 240, 213, 147, 215, 60, 20, 166, 192, 187, 213, 243, 112,
244, 244, 233, 245, 245, 128, 188, 188, 114, 174, 134, 131, 220, 174, 217,
236, 236, 198, 134, 215, 177, 58, 156, 143, 124, 25, 110, 7, 31, 228, 25, 264,
356, 368, 0, 11, 267, 451, 452, 349, 267, 302, 269, 350, 357, 277, 350, 452,
357, 299, 333, 297, 396, 175, 377, 381, 384, 382, 280, 347, 330, 269, 303,
270, 151, 9, 337, 344, 278, 360, 424, 418, 431, 270, 304, 409, 272, 310, 407,
322, 270, 410, 449, 450, 347, 432, 422, 434, 18, 313, 17, 291, 306, 375, 259,
387, 260, 424, 335, 418, 434, 364, 416, 391, 423, 327, 301, 251, 298, 275,
281, 4, 254, 373, 253, 375, 307, 321, 280, 425, 411, 200, 421, 18, 335, 321,
406, 321, 320, 405, 314, 315, 17, 423, 426, 266, 396, 377, 369, 270, 322, 269,
413, 417, 464, 385, 386, 258, 248, 456, 419, 298, 284, 333, 168, 417, 8, 448,
346, 261, 417, 413, 285, 326, 327, 328, 277, 355, 329, 309, 392, 438, 381,
382, 256, 279, 429, 360, 365, 364, 379, 355, 277, 437, 282, 443, 283, 281,
275, 363, 395, 431, 369, 299, 297, 337, 335, 273, 321, 348, 450, 349, 359,
446, 467, 283, 293, 282, 250, 458, 462, 300, 276, 383, 292, 308, 325, 283,
276, 293, 264, 372, 447, 346, 352, 340, 354, 274, 19, 363, 456, 281, 426, 436,
425, 380, 381, 252, 267, 269, 393, 421, 200, 428, 371, 266, 329, 432, 287,
422, 290, 250, 328, 385, 258, 384, 446, 265, 342, 386, 387, 257, 422, 424,
430, 445, 342, 276, 422, 273, 424, 306, 292, 307, 352, 366, 345, 268, 271,
302, 358, 423, 371, 327, 294, 460, 331, 279, 294, 303, 271, 304, 436, 432,
427, 304, 272, 408, 395, 394, 431, 378, 395, 400, 296, 334, 299, 6, 351, 168,
376, 352, 411, 307, 325, 320, 285, 295, 336, 320, 319, 404, 329, 330, 349,
334, 293, 333, 366, 323, 447, 316, 15, 315, 331, 358, 279, 317, 14, 316, 8,
285, 9, 277, 329, 350, 253, 374, 252, 319, 318, 403, 351, 6, 419, 324, 318,
325, 397, 367, 365, 288, 435, 397, 278, 344, 439, 310, 272, 311, 248, 195,
281, 375, 273, 291, 175, 396, 199, 312, 311, 268, 276, 283, 445, 390, 373,
339, 295, 282, 296, 448, 449, 346, 356, 264, 454, 337, 336, 299, 337, 338,
151, 294, 278, 455, 308, 292, 415, 429, 358, 355, 265, 340, 372, 388, 390,
466, 352, 346, 280, 295, 442, 282, 354, 19, 370, 285, 441, 295, 195, 248, 197,
457, 440, 274, 301, 300, 368, 417, 351, 465, 251, 301, 389, 385, 380, 386,
394, 395, 379, 399, 412, 419, 410, 436, 322, 387, 373, 388, 326, 2, 393, 354,
370, 461, 393, 164, 267, 268, 302, 12, 386, 374, 387, 312, 268, 13, 298, 293,
301, 265, 446, 340, 380, 385, 381, 280, 330, 425, 322, 426, 391, 420, 429,
437, 393, 391, 326, 344, 440, 438, 458, 459, 461, 364, 434, 394, 428, 396,
262, 274, 354, 457, 317, 316, 402, 316, 315, 403, 315, 314, 404, 314, 313,
405, 313, 421, 406, 323, 366, 361, 292, 306, 407, 306, 291, 408, 291, 287,
409, 287, 432, 410, 427, 434, 411, 372, 264, 383, 459, 309, 457, 366, 352,
401, 1, 274, 4, 418, 421, 262, 331, 294, 358, 435, 433, 367, 392, 289, 439,
328, 462, 326, 94, 2, 370, 289, 305, 455, 339, 254, 448, 359, 255, 446, 254,
253, 449, 253, 252, 450, 252, 256, 451, 256, 341, 452, 414, 413, 463, 286,
441, 414, 286, 258, 441, 258, 257, 442, 257, 259, 443, 259, 260, 444, 260,
467, 445, 309, 459, 250, 305, 289, 290, 305, 290, 460, 401, 376, 435, 309,
250, 392, 376, 411, 433, 453, 341, 464, 357, 453, 465, 343, 357, 412, 437,
343, 399, 344, 360, 440, 420, 437, 456, 360, 420, 363, 361, 401, 288, 265,
372, 353, 390, 339, 249, 339, 448, 255,
];
My understanding is that it takes Array[[x1,y1,z1],[x2,y2,z2],[x3,y3,z3]], each time a new set of three comes down from the matrix with the starting position being reset each time to ensure clear triangular structures.
What I would like to do is employ some different algorithms to render the facial landmarks.
There are different arrays available here:
How to get specific landmark of face like lips or eyes using tensorflow.js face-landmark-detection model
My issue is that I do not know how to manipulate the draw mesh function so that it draws liner patterns.
My attempts at integrating one of the landmarks for lips uses the array:
export const lipsUpperOuter = [61, 185, 40, 39, 37, 0, 267, 269, 270, 409, 291];
for (let i = 0; i < lipsUpperOuter.length; i++) {
const points = [lipsUpperOuter[i]].map((index) => keypoints[index]);
drawPath(ctx, points, true);
}
However this renders nothing?
My ultimate goal is to be able to define my own points A to B to C etc.. to make more artist representations of the mesh?
Does anyone know how I should adjust the method to achieve this?
I have data of length 498, and I want to convert it to an image. The data (byte array) is:
ba = [4, 41, 80, 3, 41, 130, 134, 225, 196, 184, 63, 255, 137, 50, 182, 95, 3, 86, 250, 7, 218, 114, 246, 93, 132, 101, 56, 224, 233, 234, 185, 149, 132, 245, 245, 239, 1, 171, 245, 214, 66, 198, 133, 254, 18, 19, 247, 92, 72, 151, 118, 152, 21, 131, 248, 128, 74, 103, 172, 72, 37, 163, 233, 146, 196, 54, 244, 15, 85, 91, 229, 89, 195, 22, 64, 200, 73, 131, 246, 215, 133, 166, 137, 237, 85, 27, 246, 85, 68, 70, 122, 208, 134, 179, 246, 77, 199, 119, 246, 184, 145, 147, 247, 73, 143, 217, 240, 152, 149, 3, 56, 8, 183, 58, 13, 10, 181, 131, 248, 29, 80, 8, 1, 1, 217, 131, 248, 32, 11, 248, 250, 232, 245, 99, 245, 83, 196, 22, 192, 183, 21, 156, 246, 60, 74, 104, 106, 209, 14, 212, 233, 155, 195, 248, 247, 231, 21, 236, 245, 66, 136, 87, 102, 201, 33, 92, 233, 149, 1, 200, 185, 224, 50, 100, 248, 31, 8, 184, 120, 7, 62, 20, 247, 52, 9, 136, 108, 201, 62, 4, 248, 33, 11, 185, 116, 239, 105, 156, 246, 179, 78, 40, 203, 45, 121, 204, 248, 156, 196, 117, 77, 215, 138, 20, 247, 175, 77, 57, 203, 221, 149, 156, 213, 40, 28, 186, 108, 36, 182, 252, 248, 145, 7, 185, 139, 200, 210, 180, 248, 142, 199, 167, 139, 200, 209, 252, 233, 140, 70, 248, 197, 208, 233, 12, 246, 155, 140, 105, 151, 168, 9, 213, 246, 143, 8, 152, 215, 200, 26, 29, 233, 130, 132, 249, 71, 233, 38, 37, 248, 134, 7, 199, 5, 217, 73, 69, 248, 128, 197, 214, 3, 225, 133, 93, 247, 126, 131, 215, 1, 225, 158, 237, 247, 4, 65, 7, 194, 39, 73, 28, 117, 86, 133, 198, 255, 127, 121, 165, 117, 121, 194, 24, 126, 250, 161, 45, 121, 125, 128, 246, 193, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 99, 35, 114, 51, 162, 86, 36, 33, 70, 65, 51, 69, 116, 52, 70, 70, 50, 83, 34, 54, 83, 49, 63, 67, 34, 50, 85, 109, 48, 245, 50, 98, 134, 49, 101, 1, 63, 95, 66, 101, 19, 51, 35, 55, 52, 113, 100, 82, 86, 18, 35, 114, 49, 20, 134, 67, 20, 115, 246, 36, 49, 68, 53, 19, 65, 33, 69, 52, 38, 65, 115, 19, 21, 53, 83, 68, 82, 50, 68, 113, 51, 67, 65, 47, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 211, 203]
I tried using
Image.frombuffer('L', (498), ba, 'raw', 'L', 0, 1)
But, this gave an error saying 'size must be a tuple', I tried giving (498,0) and (0,498), this gave no error, but while saving the image there was an error as 'SystemError: tile cannot extend outside image'.
You can try fromarray function
import numpy as np
image = Image.fromarray(np.array(ba).reshape(498,1))
I need to generate a sine wave to fill a char table of size 1024. The word size on the microcontroller is 16-bit and floating-point operations are not available.
The sine wave itself will oscillate between the value of 0 to 255, with 127 being the center point.
Any ideas?
You only actually need to store one quarter of the sine wave -- you can lookup the other three quarters from the first quadrant. So you only need 256 bytes.
To generate the values on the micro controller, implement CORDIC. You can store one value, and generate the whole sine wave from that.
Create a precomputed array on your PC. You only have to create a fourth of the array if ROM (or equivalent, such as flash or code segment) space is at a premium, then mirror this part out to the other 768 bytes of the array.
Write a sin table generator in your favorite language using float.
Scale and round the results to desired ranges 1024/-127..+128 (you may do that right away).
From the table, generate a source file in ASM or C, what ever works better for you.
Make sure the generated table in marked "const" in C or make go to a approbiate section in ASM so it goes to FLASH rather than RAM.
Include the file in your project.
Now intsin(x)1 is:
int intsin(int x)
limit x // 0..360° or 2PI
scale to 1024
read table at x
return x
You can improve resolution by using the table for the first quadrant only. You can than use positive values only, too (0..255). Then your intsin(x) would need to determine the quadrant and mirror the first quadrant results.
You just generate table on your PC and use it on your MCU. As somebody said you just need a quater period, but to answer your question fully, here are all 1024 chars:
for k := 0 to 1023 do
buffer[k] := (round(128+127*sin(2*pi*k/1024)));
128, 129, 130, 130, 131, 132, 133, 133, 134, 135, 136, 137, 137, 138, 139, 140, 140,
141, 142, 143, 144, 144, 145, 146, 147, 147, 148, 149, 150, 150, 151, 152, 153,
154, 154, 155, 156, 157, 157, 158, 159, 160, 160, 161, 162, 163, 163, 164, 165,
166, 166, 167, 168, 169, 169, 170, 171, 172, 172, 173, 174, 174, 175, 176, 177,
177, 178, 179, 179, 180, 181, 182, 182, 183, 184, 184, 185, 186, 186, 187, 188,
189, 189, 190, 191, 191, 192, 193, 193, 194, 195, 195, 196, 197, 197, 198, 199,
199, 200, 200, 201, 202, 202, 203, 204, 204, 205, 206, 206, 207, 207, 208, 209,
209, 210, 210, 211, 212, 212, 213, 213, 214, 214, 215, 216, 216, 217, 217, 218,
218, 219, 219, 220, 221, 221, 222, 222, 223, 223, 224, 224, 225, 225, 226, 226,
227, 227, 228, 228, 229, 229, 230, 230, 230, 231, 231, 232, 232, 233, 233, 234,
234, 234, 235, 235, 236, 236, 237, 237, 237, 238, 238, 239, 239, 239, 240, 240,
240, 241, 241, 241, 242, 242, 242, 243, 243, 243, 244, 244, 244, 245, 245, 245,
246, 246, 246, 246, 247, 247, 247, 248, 248, 248, 248, 249, 249, 249, 249, 250,
250, 250, 250, 250, 251, 251, 251, 251, 251, 252, 252, 252, 252, 252, 252, 253,
253, 253, 253, 253, 253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254,
254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254,
254, 254, 254, 254, 254, 254, 254, 254, 254, 253, 253, 253, 253, 253, 253, 253,
252, 252, 252, 252, 252, 252, 251, 251, 251, 251, 251, 250, 250, 250, 250, 250,
249, 249, 249, 249, 248, 248, 248, 248, 247, 247, 247, 246, 246, 246, 246, 245,
245, 245, 244, 244, 244, 243, 243, 243, 242, 242, 242, 241, 241, 241, 240, 240,
240, 239, 239, 239, 238, 238, 237, 237, 237, 236, 236, 235, 235, 234, 234, 234,
233, 233, 232, 232, 231, 231, 230, 230, 230, 229, 229, 228, 228, 227, 227, 226,
226, 225, 225, 224, 224, 223, 223, 222, 222, 221, 221, 220, 219, 219, 218, 218,
217, 217, 216, 216, 215, 214, 214, 213, 213, 212, 212, 211, 210, 210, 209, 209,
208, 207, 207, 206, 206, 205, 204, 204, 203, 202, 202, 201, 200, 200, 199, 199,
198, 197, 197, 196, 195, 195, 194, 193, 193, 192, 191, 191, 190, 189, 189, 188,
187, 186, 186, 185, 184, 184, 183, 182, 182, 181, 180, 179, 179, 178, 177, 177,
176, 175, 174, 174, 173, 172, 172, 171, 170, 169, 169, 168, 167, 166, 166, 165,
164, 163, 163, 162, 161, 160, 160, 159, 158, 157, 157, 156, 155, 154, 154, 153,
152, 151, 150, 150, 149, 148, 147, 147, 146, 145, 144, 144, 143, 142, 141, 140,
140, 139, 138, 137, 137, 136, 135, 134, 133, 133, 132, 131, 130, 130, 129, 128,
127, 126, 126, 125, 124, 123, 123, 122, 121, 120, 119, 119, 118, 117, 116, 116,
115, 114, 113, 112, 112, 111, 110, 109, 109, 108, 107, 106, 106, 105, 104, 103,
102, 102, 101, 100, 99, 99, 98, 97, 96, 96, 95, 94, 93, 93, 92, 91,
90, 90, 89, 88, 87, 87, 86, 85, 84, 84, 83, 82, 82, 81, 80, 79,
79, 78, 77, 77, 76, 75, 74, 74, 73, 72, 72, 71, 70, 70, 69, 68,
67, 67, 66, 65, 65, 64, 63, 63, 62, 61, 61, 60, 59, 59, 58, 57,
57, 56, 56, 55, 54, 54, 53, 52, 52, 51, 50, 50, 49, 49, 48, 47,
47, 46, 46, 45, 44, 44, 43, 43, 42, 42, 41, 40, 40, 39, 39, 38,
38, 37, 37, 36, 35, 35, 34, 34, 33, 33, 32, 32, 31, 31, 30, 30,
29, 29, 28, 28, 27, 27, 26, 26, 26, 25, 25, 24, 24, 23, 23, 22,
22, 22, 21, 21, 20, 20, 19, 19, 19, 18, 18, 17, 17, 17, 16, 16,
16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11,
10, 10, 10, 10, 9, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6,
6, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 3,
3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6,
7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11,
11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16,
16, 17, 17, 17, 18, 18, 19, 19, 19, 20, 20, 21, 21, 22, 22, 22,
23, 23, 24, 24, 25, 25, 26, 26, 26, 27, 27, 28, 28, 29, 29, 30,
30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 37, 37, 38, 38,
39, 39, 40, 40, 41, 42, 42, 43, 43, 44, 44, 45, 46, 46, 47, 47,
48, 49, 49, 50, 50, 51, 52, 52, 53, 54, 54, 55, 56, 56, 57, 57,
58, 59, 59, 60, 61, 61, 62, 63, 63, 64, 65, 65, 66, 67, 67, 68,
69, 70, 70, 71, 72, 72, 73, 74, 74, 75, 76, 77, 77, 78, 79, 79,
80, 81, 82, 82, 83, 84, 84, 85, 86, 87, 87, 88, 89, 90, 90, 91,
92, 93, 93, 94, 95, 96, 96, 97, 98, 99, 99, 100, 101, 102, 102, 103,
104, 105, 106, 106, 107, 108, 109, 109, 110, 111, 112, 112, 113, 114, 115, 116,
116, 117, 118, 119, 119, 120, 121, 122, 123, 123, 124, 125, 126, 126, 127