Added Arduino and Compression
This commit is contained in:
parent
838e6e9d89
commit
b023b561d8
46
Arduino/CompressionTest1/CompressionTest1.ino
Normal file
46
Arduino/CompressionTest1/CompressionTest1.ino
Normal file
@ -0,0 +1,46 @@
|
||||
#include <bcconfig.h>
|
||||
#include <BigNumber.h>
|
||||
#include <number.h>
|
||||
|
||||
#define numberOfSensors 50
|
||||
int flexSensorPins[] = {A0, A1, A2, A3};
|
||||
|
||||
int mapValue;
|
||||
String reference[] = {"L","H","R"};
|
||||
String finalReadable;
|
||||
String final;
|
||||
int i = 0;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
BigNumber::begin();
|
||||
}
|
||||
|
||||
String compression(int values[]) {
|
||||
String combinedInt = "";
|
||||
String header = "";
|
||||
for (i = 0; i < numberOfSensors; i++) {
|
||||
if(values[i] < 10) {
|
||||
if(values[i] < 0) {
|
||||
header += String(i) + ",";
|
||||
combinedInt += String(values[i] * -1);
|
||||
} else {
|
||||
combinedInt += "0" + String(values[i]);
|
||||
}
|
||||
} else {
|
||||
combinedInt += String(values[i]);
|
||||
}
|
||||
}
|
||||
return header.substring(0,header.length()-1) + "." + combinedInt;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
finalReadable = "";
|
||||
final = "";
|
||||
int dataValues[] = {32, 62, 10, 7, -45, 91, -95, 27, 54, 50, 67, 84, 92,
|
||||
68, 10, 53, 79, 65, 06, 62, 60, -15, 52, 63, 71, 9,
|
||||
52, -86, 68, 52, 96, 30, 31, 50, 24, 56, -61, 54, 40, 26,
|
||||
33, 34, 32, 28, 2, 96, 3, 77, 66, 97};
|
||||
Serial.println(compression(dataValues));
|
||||
delay(250);
|
||||
}
|
||||
88
Arduino/CompressionTest2/CompressionTest2.ino
Normal file
88
Arduino/CompressionTest2/CompressionTest2.ino
Normal file
@ -0,0 +1,88 @@
|
||||
#include <bcconfig.h>
|
||||
#include <BigNumber.h>
|
||||
#include <number.h>
|
||||
|
||||
#define numberOfSensors 50
|
||||
int flexSensorPins[] = {A0, A1, A2, A3};
|
||||
|
||||
int mapValue;
|
||||
String reference[] = {"L","H"};
|
||||
String finalReadable;
|
||||
String final;
|
||||
int i = 0;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
BigNumber::begin();
|
||||
|
||||
}
|
||||
|
||||
String toBinary(String intString, int len) {
|
||||
String binary = "";
|
||||
char s[len];
|
||||
intString.toCharArray(s, len);
|
||||
BigNumber lrgInt(s);
|
||||
BigNumber two = 2;
|
||||
BigNumber zero = 0;
|
||||
int remainder;
|
||||
|
||||
while (lrgInt > zero) {
|
||||
remainder = lrgInt % two;
|
||||
lrgInt = lrgInt / two;
|
||||
lrgInt = lrgInt - lrgInt % lrgInt
|
||||
lrgInt
|
||||
binary = String(remainder) + binary;
|
||||
Serial.println(binary);
|
||||
}
|
||||
return binary;
|
||||
}
|
||||
|
||||
String compression(int values[]) {
|
||||
String finalCompress = "";
|
||||
String combinedInt = "";
|
||||
String binString = "";
|
||||
char* s;
|
||||
int counter = 0;
|
||||
int change = 0;
|
||||
for (i = 0; i < numberOfSensors; i++) {
|
||||
if(String(values[i]).length() < 2) {
|
||||
combinedInt += "0" + String(values[i]);
|
||||
} else {
|
||||
combinedInt += String(values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
binString = toBinary(combinedInt, combinedInt.length());
|
||||
|
||||
for (i = 0; i <= binString.length(); i++) {
|
||||
if (binString.charAt(i) == binString.charAt(change)) {
|
||||
counter += 1;
|
||||
} else {
|
||||
if(counter == 1) {
|
||||
finalCompress = finalCompress + reference[String(binString.charAt(0)).toInt()];
|
||||
} else {
|
||||
finalCompress = finalCompress + String(counter) + reference[String(binString.charAt(0)).toInt()];
|
||||
}
|
||||
change = i;
|
||||
counter = 1;
|
||||
}
|
||||
}
|
||||
return finalCompress;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
finalReadable = "";
|
||||
final = "";
|
||||
int dataValues[] = {32, 62, 10, 7, 45, 91, 95, 27, 54, 50, 67, 84, 92, 68, 10,
|
||||
53, 79, 65, 6, 62, 60, 15, 52, 63, 71, 9, 52, 86,
|
||||
68, 52, 96, 30, 31, 50, 24, 56, 61, 54, 40, 26,
|
||||
33, 34, 32, 28, 2, 96, 3, 77, 66, 97};
|
||||
|
||||
//for(int i = 0; i < numberOfSensors; i++) {
|
||||
//mapValue = map(analogRead(flexSensorPins[i]), 512, 853, 0, 180) - 25;
|
||||
//finalReadable = finalReadable + String(mapValue) + ",";
|
||||
//dataValues[i] = mapValue;
|
||||
String hello = compression(dataValues);
|
||||
//Serial.println(hello);
|
||||
delay(250);
|
||||
}
|
||||
46
Arduino/FlexTest/FlexTest.ino
Normal file
46
Arduino/FlexTest/FlexTest.ino
Normal file
@ -0,0 +1,46 @@
|
||||
#define numberOfSensors 3
|
||||
int muxPins[] = {5,6,7};
|
||||
int dataPin = A0;
|
||||
int lastDataValues[] = {0,0,0};
|
||||
int i = 0;
|
||||
|
||||
String delLast(String input) {
|
||||
return input.substring(0,input.length()-1);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
for(i = 0; i < sizeof(muxPins); i++) {
|
||||
pinMode(muxPins[i],OUTPUT);
|
||||
digitalWrite(muxPins[i],LOW);
|
||||
}
|
||||
pinMode(dataPin, INPUT);
|
||||
Serial.begin(115200);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
digitalWrite(5,LOW);digitalWrite(6,LOW);digitalWrite(7,HIGH);
|
||||
String finalShort = "";
|
||||
String finalReal = "";
|
||||
String raw = "";
|
||||
int mapValue = 0;
|
||||
|
||||
for(int i = 0; i < numberOfSensors; i++) {
|
||||
String bin = String(i,BIN);
|
||||
while(bin.length() < 3) {
|
||||
bin = "0" + bin;
|
||||
}
|
||||
|
||||
for(int j = 0; j < 3; j++) {
|
||||
digitalWrite(muxPins[j],bin.substring(bin.length()-j-1,bin.length()-j).toInt());
|
||||
}
|
||||
|
||||
mapValue = map(analogRead(dataPin), 530, 810, 0, 180);
|
||||
finalShort = finalShort + String(mapValue - lastDataValues[i]) + ",";
|
||||
finalReal = finalReal + String(mapValue) + ",";
|
||||
raw = raw + String(analogRead(dataPin)) + ",";
|
||||
lastDataValues[i] = mapValue;
|
||||
}
|
||||
|
||||
Serial.println(delLast(raw) + " :: " + delLast(finalReal) + " :: " + delLast(finalShort));
|
||||
delay(100);
|
||||
}
|
||||
192
Arduino/MPU6050_Multi/MPU6050_Multi.ino
Normal file
192
Arduino/MPU6050_Multi/MPU6050_Multi.ino
Normal file
@ -0,0 +1,192 @@
|
||||
// I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class using DMP (MotionApps v2.0)
|
||||
// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
|
||||
// is used in I2Cdev.h
|
||||
#include "Wire.h"
|
||||
/* I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
|
||||
* for both classes must be in the include path of your project
|
||||
*/
|
||||
#include "I2Cdev.h"
|
||||
#include "MPU6050_6Axis_MotionApps20.h"
|
||||
|
||||
#define NUMBER_OF_SENSORS 3 //// YOU MAY NEED TO CHANGE THIS
|
||||
|
||||
// Default I2C address is 0x68
|
||||
// AD0 LOW(0) = 0x68 (Default for SparkFun breakout and InvenSense evaluation board)
|
||||
// AD0 HIGH(1) = 0x69
|
||||
|
||||
// MPU Control Variables
|
||||
MPU6050 mpu;
|
||||
bool dmpReady; // Set true if DMP init was successful.
|
||||
uint8_t devStatus; // Return status after each device operation. (0 = success, !0 = error)
|
||||
uint8_t mpuIntStatus; // Holds interrupt status byte from MPU.
|
||||
uint16_t packetSize; // Expected DMP packet size. (Default is 42 bytes)
|
||||
uint16_t fifoCount; // Count of all bytes currently in FIFO.
|
||||
uint8_t fifoBuffer[64]; // FIFO storage buffer.
|
||||
|
||||
// Orientation and Motion Variables
|
||||
Quaternion q; // [W, X, Y, Z] Quaternion container.
|
||||
VectorFloat gravity; // [X, Y, Z] Gravity vector
|
||||
float ypr[3]; // [Yaw, Pitch, Roll] array container.
|
||||
|
||||
//Digital Pins Reference Variables
|
||||
const int latchPin = 2; //ST_CP or RCLK
|
||||
const int clockPin = 1; //SH_CP or SRCLK
|
||||
const int dataPin = 3; //DS or SER
|
||||
|
||||
// Other Variables
|
||||
String finalParts[NUMBER_OF_SENSORS];
|
||||
String final = "";
|
||||
|
||||
//==============================================================
|
||||
|
||||
void switchSensor(int sensorNumber) {
|
||||
/* The shift register shifts out bits to the ADO lines. In binary:
|
||||
* 0001 = Sensor on Q0(QA) 2^0 = 1 = 0001 in binary
|
||||
* 0010 = Sensor on Q1(QB) 2^1 = 2 = 0010 in binary
|
||||
*/
|
||||
int data = (int) 1 << (sensorNumber - 1); // Shift register serial data input.
|
||||
|
||||
digitalWrite(latchPin, LOW); // Hold low for as long as you are transmitting data.
|
||||
shiftOutBits(dataPin, clockPin, ~data); // Shift out the bits into the shift register; negate data. (0001 = 1000)
|
||||
digitalWrite(latchPin, HIGH); // Ends transmission of data.
|
||||
}
|
||||
|
||||
void shiftOutBits(int myDataPin, int myClockPin, byte myDataOut) {
|
||||
// This shifts 8 bits out MSB first.
|
||||
|
||||
//Function Setup
|
||||
int l = 0;
|
||||
int pinState;
|
||||
|
||||
pinMode(myClockPin, OUTPUT);
|
||||
pinMode(myDataPin, OUTPUT);
|
||||
|
||||
// Clear everything out in case to prepare shift register.
|
||||
digitalWrite(myDataPin, 0);
|
||||
digitalWrite(myClockPin, 0);
|
||||
|
||||
// For each bit in the byte myDataOut.
|
||||
for (l = 7; l >= 0; l--) {
|
||||
digitalWrite(myClockPin, 0);
|
||||
|
||||
//if the value passed to myDataOut and a bitmask result
|
||||
// true then... so if we are at i=6 and our value is
|
||||
// %11010100 it would the code compares it to %01000000
|
||||
// and proceeds to set pinState to 1.
|
||||
if ( myDataOut & (1 << l) ) {
|
||||
pinState = 1;
|
||||
//////Serial.print(pinState);
|
||||
}
|
||||
else {
|
||||
pinState = 0;
|
||||
//////Serial.print(pinState);
|
||||
}
|
||||
// Sets the pin to HIGH or LOW depending on pinState.
|
||||
digitalWrite(myDataPin, pinState);
|
||||
// Register shifts on HIGH of myClockPin.
|
||||
digitalWrite(myClockPin, 1);
|
||||
// Stop sending on myDataPin.
|
||||
digitalWrite(myDataPin, 0);
|
||||
}
|
||||
// Stop shifting.
|
||||
digitalWrite(myClockPin, 0);
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// === MAIN PROGRAM SETUP ===
|
||||
// ================================================================
|
||||
|
||||
void setup() {
|
||||
delay(2000);
|
||||
|
||||
Wire.begin(); // Join I2C bus. (I2Cdev library doesn't do this automatically.)
|
||||
TWBR = 24; // Sets frequency of the clock (SCL) higher.
|
||||
|
||||
|
||||
Serial.begin(115200); // Initialize serial communication with baud rate.
|
||||
|
||||
pinMode(latchPin, OUTPUT); // Tell the Arduino to send or recieve signals.
|
||||
|
||||
int dmpReadyCounter = 0; // Counts number of sensors ready.
|
||||
|
||||
for (int i = 1; i <= NUMBER_OF_SENSORS; i++) {
|
||||
/* We read data from all sensors by switching addresses one by one, only reading from the first address (0x68).
|
||||
* Therefore, we shift the addresses to the next sensor, and retrieve its value.
|
||||
*/
|
||||
switchSensor(i);
|
||||
|
||||
mpu.initialize(); // Intialize device.
|
||||
|
||||
devStatus = mpu.dmpInitialize(); // Load and configure the DMP. (Digital Motion Processor)
|
||||
|
||||
// Gyroscope offsets. (Change if necessary)
|
||||
mpu.setXGyroOffset(220);
|
||||
mpu.setYGyroOffset(76);
|
||||
mpu.setZGyroOffset(-85);
|
||||
mpu.setZAccelOffset(1788);
|
||||
|
||||
// Check success of DMP.
|
||||
if (devStatus == 0) {
|
||||
mpu.setDMPEnabled(true);
|
||||
|
||||
dmpReadyCounter += 1; // Add one to count number of ready sensors.
|
||||
|
||||
packetSize = mpu.dmpGetFIFOPacketSize(); // Get expected DMP packet size for later comparison
|
||||
} else {
|
||||
// Error!
|
||||
Serial.print("Error on sensor " + String(i) + "\n");
|
||||
}
|
||||
/////////Serial.print(String(digitalRead(8)) + String(digitalRead(9)) + String(digitalRead(10)) + String(digitalRead(11)) + "\n");
|
||||
}
|
||||
if (dmpReadyCounter == 3) {
|
||||
dmpReady = true; // Set DMP Ready flag. (Allows main loop to use the DMP.)
|
||||
}
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// === MAIN PROGRAM LOOP ===
|
||||
// ================================================================
|
||||
|
||||
void loop() {
|
||||
final = ""; // Reset final to nothing.
|
||||
// If DMP isn't ready...
|
||||
if (!(dmpReady)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int k = 1; k <= NUMBER_OF_SENSORS; k++) {
|
||||
|
||||
switchSensor(k);
|
||||
|
||||
// Check for overflow.
|
||||
if (fifoCount == 1024) {
|
||||
mpu.resetFIFO(); // Reset so we can continue cleanly.
|
||||
} else {
|
||||
fifoCount = mpu.getFIFOCount(); // Get current FIFO count.
|
||||
|
||||
// Wait for correct avaliable data length.
|
||||
while (fifoCount < packetSize) {
|
||||
fifoCount = mpu.getFIFOCount();
|
||||
}
|
||||
|
||||
mpu.getFIFOBytes(fifoBuffer, packetSize); // Read a packet from FIFO
|
||||
/* Track FIFO count in case there is more than 1 packet avaliable.
|
||||
* (Read more without waiting for an interrupt.)
|
||||
*/
|
||||
fifoCount -= packetSize;
|
||||
|
||||
// Get values to process.
|
||||
mpu.dmpGetQuaternion(&q, fifoBuffer);
|
||||
mpu.dmpGetGravity(&gravity, &q);
|
||||
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
|
||||
|
||||
// Concatenate for outputting. (Displays in Euler Angles in degrees.)
|
||||
finalParts[k - 1] = String(ypr[0] * 180 / M_PI) + "," + String(ypr[1] * 180 / M_PI) + "," + String(ypr[2] * 180 / M_PI) + ":";
|
||||
final += finalParts[k - 1];
|
||||
}
|
||||
}
|
||||
Serial.print(final);
|
||||
Serial.print("\n");
|
||||
}
|
||||
|
||||
|
||||
30
Arduino/MUXTest/MUXTest.ino
Normal file
30
Arduino/MUXTest/MUXTest.ino
Normal file
@ -0,0 +1,30 @@
|
||||
int muxPins[3] = {5,6,7};
|
||||
int dataPin = 13;
|
||||
|
||||
void setup() {
|
||||
for(int i = 0; i < 3; i++) {
|
||||
pinMode(muxPins[i],OUTPUT);
|
||||
digitalWrite(muxPins[i],LOW);
|
||||
}
|
||||
pinMode(dataPin, OUTPUT);
|
||||
digitalWrite(dataPin,HIGH);
|
||||
Serial.begin(115200);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
String bin = String(i,BIN);
|
||||
while(bin.length() < 3) {
|
||||
bin = "0" + bin;
|
||||
}
|
||||
|
||||
for(int j = 0; j < 3; j++) {
|
||||
digitalWrite(muxPins[j],bin.substring(bin.length()-j-1,bin.length()-j).toInt());
|
||||
}
|
||||
Serial.println(" ");
|
||||
delay(50);
|
||||
}
|
||||
|
||||
// put your main code here, to run repeatedly:
|
||||
|
||||
}
|
||||
75
Arduino/MotorTest/MotorTest.ino
Normal file
75
Arduino/MotorTest/MotorTest.ino
Normal file
@ -0,0 +1,75 @@
|
||||
int inA1 = 8; // wire 1 (blue)
|
||||
int inA2 = 9; // wire 2 (pink)
|
||||
int inB1 = 10; // wire 3 (yellow)
|
||||
int inB2 = 11; // wire 4 (orange)
|
||||
int counter = 0;
|
||||
//wire 5 (Red) is a VCC and should be put to 5V, with this setup it is not needed, but it is good to know if you make something like an 8 step spinup
|
||||
|
||||
int stepDelay = 2;
|
||||
|
||||
void setup() {
|
||||
pinMode(inA1, OUTPUT);
|
||||
pinMode(inA2, OUTPUT);
|
||||
pinMode(inB1, OUTPUT);
|
||||
pinMode(inB2, OUTPUT);
|
||||
pinMode(A1,INPUT);
|
||||
}
|
||||
void loop(){
|
||||
|
||||
Serial.println(String(analogRead(A1)));
|
||||
Serial.println("hi");
|
||||
/*for(int i =0;i<1600;i++) {
|
||||
step1();
|
||||
step2();
|
||||
step3();
|
||||
step4();
|
||||
}
|
||||
stopMotor();
|
||||
delay(500);
|
||||
|
||||
for(int j=0;j<1600;j++) {
|
||||
step3();
|
||||
step2();
|
||||
step1();
|
||||
step4();
|
||||
}
|
||||
stopMotor();
|
||||
delay(500);*/
|
||||
}
|
||||
|
||||
void step1() {
|
||||
digitalWrite(inA1, LOW);
|
||||
digitalWrite(inA2, HIGH);
|
||||
digitalWrite(inB1, HIGH);
|
||||
digitalWrite(inB2, LOW);
|
||||
delay(stepDelay);
|
||||
|
||||
}
|
||||
void step2() {
|
||||
digitalWrite(inA1, LOW);
|
||||
digitalWrite(inA2, HIGH);
|
||||
digitalWrite(inB1, LOW);
|
||||
digitalWrite(inB2, HIGH);
|
||||
delay(stepDelay);
|
||||
}
|
||||
void step3() {
|
||||
digitalWrite(inA1, HIGH);
|
||||
digitalWrite(inA2, LOW);
|
||||
digitalWrite(inB1, LOW);
|
||||
digitalWrite(inB2, HIGH);
|
||||
delay(stepDelay);
|
||||
}
|
||||
void step4() {
|
||||
digitalWrite(inA1, HIGH);
|
||||
digitalWrite(inA2, LOW);
|
||||
digitalWrite(inB1, HIGH);
|
||||
digitalWrite(inB2, LOW);
|
||||
delay(stepDelay);
|
||||
}
|
||||
void stopMotor() {
|
||||
digitalWrite(inA1, LOW);
|
||||
digitalWrite(inA2, LOW);
|
||||
digitalWrite(inB1, LOW);
|
||||
digitalWrite(inB2, LOW);
|
||||
}
|
||||
|
||||
67
Arduino/SevenSegmentLED/SevenSegmentLED.ino
Normal file
67
Arduino/SevenSegmentLED/SevenSegmentLED.ino
Normal file
@ -0,0 +1,67 @@
|
||||
const int latchPin = 8; //ST_CP or RCLK
|
||||
const int clockPin = 12; //SH_CP or SRCLK
|
||||
const int dataPin = 11; //DS or SER
|
||||
|
||||
byte seven_seg_digits[10][7] = {
|
||||
{ 1,1,1,1,1,1,0 }, // = 0
|
||||
{ 0,1,1,0,0,0,0 }, // = 1
|
||||
{ 1,1,0,1,1,0,1 }, // = 2
|
||||
{ 1,1,1,1,0,0,1 }, // = 3
|
||||
{ 0,1,1,0,0,1,1 }, // = 4
|
||||
{ 1,0,1,1,0,1,1 }, // = 5
|
||||
{ 1,0,1,1,1,1,1 }, // = 6
|
||||
{ 1,1,1,0,0,0,0 }, // = 7
|
||||
{ 1,1,1,1,1,1,1 }, // = 8
|
||||
{ 1,1,1,0,0,1,1 } // = 9
|
||||
};
|
||||
|
||||
int digits[10] = {
|
||||
126, 48, 109, 121, 51, 91, 95, 112, 127,
|
||||
}
|
||||
|
||||
|
||||
void writeNumber(int character) {
|
||||
/* The shift register shifts out bits to the ADO lines. In binary:
|
||||
* 1110 = Sensor on Q0(QA) ~(2^0) = ~1 = 1110 in binary
|
||||
* 1101 = Sensor on Q1(QB) ~(2^1) = ~2 = 1101 in binary
|
||||
* '~' = not
|
||||
*/
|
||||
//int data = (int) 1 << (sensorNumber - 1); // Shift register serial data input.
|
||||
|
||||
digitalWrite(latchPin, LOW); // Hold low for as long as you are transmitting data.
|
||||
shiftOutBits(dataPin, clockPin, character); // Shift out the bits into the shift register; negate data. (0001 = 1000)
|
||||
digitalWrite(latchPin, HIGH); // Ends transmission of data.
|
||||
}
|
||||
|
||||
void shiftOutBits(int myDataPin, int myClockPin, int number) {
|
||||
// This shifts 8 bits out MSB first.
|
||||
|
||||
// Setup Varaibles
|
||||
int pinState;
|
||||
|
||||
pinMode(myClockPin, OUTPUT);
|
||||
pinMode(myDataPin, OUTPUT);
|
||||
|
||||
// Clear everything out in case to prepare shift register.
|
||||
digitalWrite(myDataPin, 0);
|
||||
digitalWrite(myClockPin, 0);
|
||||
|
||||
// For each bit in the byte myDataOut.
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
digitalWrite(myClockPin, 0);
|
||||
|
||||
pinState = 1 - seven_seg_digits[number][i];
|
||||
digitalWrite(myDataPin, pinState); // Sets the pin to HIGH or LOW depending on pinState.
|
||||
digitalWrite(myClockPin, 1); // Register shifts on HIGH of myClockPin.
|
||||
digitalWrite(myDataPin, 0); // Stop sending on myDataPin.
|
||||
}
|
||||
digitalWrite(myClockPin, 0); // Stop shifting.
|
||||
}
|
||||
|
||||
void setup() {
|
||||
writeNumber(5);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
return;
|
||||
}
|
||||
54
Arduino/Transfer.py
Normal file
54
Arduino/Transfer.py
Normal file
@ -0,0 +1,54 @@
|
||||
import serial
|
||||
port = serial.Serial('COM6', 9600)
|
||||
valuesBeforeAveraging = 6
|
||||
numberOfSensors = 3
|
||||
splitValues = []
|
||||
averageSetLength = 0
|
||||
nan = ['nan','na']
|
||||
|
||||
def getNewValue():
|
||||
newRead = port.readline()[:-2].lower()
|
||||
if nan[0] in newRead or nan[1] in newRead:
|
||||
print "FIFO Buffer Overflow"
|
||||
getNewValue()
|
||||
else:
|
||||
return newRead
|
||||
|
||||
def getNewAverage(newValue):
|
||||
global splitValues
|
||||
global averageSetLength
|
||||
average = 0.0000
|
||||
outputLine = ""
|
||||
|
||||
splitValues.append([]) # Append new trial
|
||||
|
||||
if averageSetLength > valuesBeforeAveraging:
|
||||
del splitValues[0]
|
||||
|
||||
averageSetLength = len(splitValues)
|
||||
|
||||
for yprNum, ypr in enumerate(newValue.split(":")): # For each sensor/YPR set
|
||||
splitValues[averageSetLength - 1].append([]) # Append new array, compensate for array start 0
|
||||
|
||||
for valueNum, value in enumerate(ypr.split(",")): # For each value in YPR set
|
||||
splitValues[averageSetLength - 1][yprNum].append(float(value)) # Append value to array
|
||||
|
||||
for entryNum in xrange(0, averageSetLength): #For all trials
|
||||
average += splitValues[entryNum][yprNum][valueNum] # Add all x,y,z values
|
||||
average = average / (averageSetLength) # Divide by number of trials
|
||||
outputLine = outputLine + str(average)[:str(average).find('.') + 4] + ","
|
||||
average = 0.0000
|
||||
outputLine = outputLine[:-1] + ":"
|
||||
outputLine = outputLine[:-1]
|
||||
|
||||
return outputLine
|
||||
|
||||
while 1:
|
||||
try:
|
||||
newRead = getNewValue()
|
||||
final = getNewAverage(newRead)
|
||||
print final
|
||||
file = open('Transfer.txt','w')
|
||||
file.write(final)
|
||||
file.close()
|
||||
except: IOError
|
||||
86
Arduino/shiftOutTest/shiftOutTest.ino
Normal file
86
Arduino/shiftOutTest/shiftOutTest.ino
Normal file
@ -0,0 +1,86 @@
|
||||
//**************************************************************//
|
||||
// Name : shiftOutCode, Dual Binary Counters //
|
||||
// Author : Carlyn Maw, Tom Igoe //
|
||||
// Date : 25 Oct, 2006 //
|
||||
// Version : 1.0 //
|
||||
// Notes : Code for using a 74HC595 Shift Register //
|
||||
// : to count from 0 to 255 //
|
||||
//**************************************************************//
|
||||
|
||||
//Pin connected to ST_CP of 74HC595
|
||||
int latchPin = 2;
|
||||
//Pin connected to SH_CP of 74HC595
|
||||
int clockPin = 1;
|
||||
////Pin connected to DS of 74HC595
|
||||
int dataPin = 3;
|
||||
|
||||
|
||||
|
||||
void setup() {
|
||||
//Start Serial for debuging purposes
|
||||
Serial.begin(9600);
|
||||
//set pins to output because they are addressed in the main loop
|
||||
pinMode(latchPin, OUTPUT);
|
||||
digitalWrite(5, LOW);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
//count up routine
|
||||
//ground latchPin and hold low for as long as you are transmitting
|
||||
digitalWrite(latchPin, 0);
|
||||
//count down on RED LEDs
|
||||
shiftOut(dataPin, clockPin, 2);
|
||||
//return the latch pin high to signal chip that it
|
||||
//no longer needs to listen for information
|
||||
digitalWrite(latchPin, 1);
|
||||
delay(1000);
|
||||
Serial.print(String(digitalRead(8)) + String(digitalRead(9)) + String(digitalRead(10)) + String(digitalRead(11)) + "\n");
|
||||
//Serial.print(digitalRead(8));
|
||||
}
|
||||
|
||||
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
|
||||
// This shifts 8 bits out MSB first,
|
||||
//on the rising edge of the clock,
|
||||
//clock idles low
|
||||
|
||||
//internal function setup
|
||||
int i=0;
|
||||
int pinState;
|
||||
pinMode(myClockPin, OUTPUT);
|
||||
pinMode(myDataPin, OUTPUT);
|
||||
|
||||
//clear everything out just in case to
|
||||
//prepare shift register for bit shifting
|
||||
digitalWrite(myDataPin, 0);
|
||||
digitalWrite(myClockPin, 0);
|
||||
|
||||
//for each bit in the byte myDataOut<75>
|
||||
//NOTICE THAT WE ARE COUNTING DOWN in our for loop
|
||||
//This means that %00000001 or "1" will go through such
|
||||
//that it will be pin Q0 that lights.
|
||||
for (i=7; i>=0; i--) {
|
||||
digitalWrite(myClockPin, 0);
|
||||
|
||||
//if the value passed to myDataOut and a bitmask result
|
||||
// true then... so if we are at i=6 and our value is
|
||||
// %11010100 it would the code compares it to %01000000
|
||||
// and proceeds to set pinState to 1.
|
||||
if ( myDataOut & (1<<i) ) {
|
||||
pinState= 1;
|
||||
}
|
||||
else {
|
||||
pinState= 0;
|
||||
}
|
||||
|
||||
//Sets the pin to HIGH or LOW depending on pinState
|
||||
digitalWrite(myDataPin, pinState);
|
||||
//register shifts bits on upstroke of clock pin
|
||||
digitalWrite(myClockPin, 1);
|
||||
//zero the data pin after shift to prevent bleed through
|
||||
digitalWrite(myDataPin, 0);
|
||||
}
|
||||
|
||||
//stop shifting
|
||||
digitalWrite(myClockPin, 0);
|
||||
}
|
||||
BIN
Compression/3DBlocks.png
Normal file
BIN
Compression/3DBlocks.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 MiB |
BIN
Compression/4DBlocks.png
Normal file
BIN
Compression/4DBlocks.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
125
Compression/Algorithm Details.tex
Normal file
125
Compression/Algorithm Details.tex
Normal file
@ -0,0 +1,125 @@
|
||||
\documentclass{article}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[margin=1in]{geometry}
|
||||
\usepackage{amsfonts, amsmath, amssymb}
|
||||
\usepackage[none]{hyphenat}
|
||||
\usepackage{fancyhdr}
|
||||
\usepackage{titling}
|
||||
\usepackage{changepage}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{wrapfig}
|
||||
|
||||
\renewcommand\maketitlehooka{\null\mbox{}\vfill}
|
||||
\renewcommand\maketitlehookd{\vfill\null}
|
||||
|
||||
\pagestyle{fancy}
|
||||
\fancyhead[L]{\slshape Algorithm Details}
|
||||
\fancyhead[R]{Kenneth Jao}
|
||||
\fancyfoot[C]{\thepage}
|
||||
|
||||
\title{Lossy Compression through Multi-dimensional Fourier Transforms }
|
||||
\author{Kenneth Jao}
|
||||
\date{February 2019}
|
||||
|
||||
\begin{document}
|
||||
\maketitle
|
||||
\pagebreak
|
||||
|
||||
\section{Introduction}
|
||||
This document covers the details of the mathematics of the compression algorithm. Each main mathematical application will be explained in detail. Firstly an overview of the algorithm as a whole will be given.
|
||||
|
||||
\subsection{Notation}
|
||||
\begin{adjustwidth}{.5in}{}
|
||||
Data Matrix: \[ \left[ {\begin{array}{cccc} A & B & C & \dots \end{array}} \right] or \left[\ A,\ B,\ C,\ \dots \ \right]\]
|
||||
Will mean that the dimensions 0, 1, 2, \dots will correspond to A, B, C, \dots and represents an array of data, not a mathematical matrix.\\
|
||||
\newline
|
||||
N-Dimensional Polynomial:\\
|
||||
\begin{adjustwidth}{.5in}{}
|
||||
$\vec{e_i}=(e_1,\ e_2,\ e_3, \dots e_n) \in \mathbb{N}^n$ will represent the i-th permutation of $\vec{e}$.\\
|
||||
$\vec{x}^{\vec{e}} = x_1^{e_1}\cdot x_2^{e_2}\cdot \dots x_n^{e_n}$ where $\vec{x}=(x_1,\ x_2,\ x_3, \dots x_n) \in \mathbb{R}^n$\\
|
||||
An arbitrary n-dimensional polynomial of degree m $P(\ x_1,\ x_2,\ x_3,\dots,\ x_n)$ will equal: \[ a_1x^{\vec{e_1}} + a_2x^{\vec{e_2}} + a_3x^{\vec{e_3}} + \dots + a_{max}x^{\vec{e_{max}}}\]
|
||||
Where $max=(m+1)^n$
|
||||
\end{adjustwidth}
|
||||
|
||||
\end{adjustwidth}
|
||||
|
||||
\subsection{Algorithm Overview}
|
||||
|
||||
\begin{adjustwidth}{.5in}{}
|
||||
A set of video data in given in the format: \[ \left[ {\begin{array}{cccc} Frame & Y Pixel & X Pixel & RGB \end{array}} \right] \]
|
||||
After receiving this video data, it will be processed into square blocks of dimension $N$, denoted by $Block_{w_1,w_2,w_3,...}$ where ${w_1, w_2, w_3,...}$ represents the sorting of $N$ dimensional blocks in a format that correspond to the location of the data in the ordered video. For instance, given a data in format $[\ x,\ y,\ z\ ]$, square blocks of dimension $N$ can be extracted such that the new data structure is now in the form $[\frac{x}{N},\frac{y}{N},\frac{z}{N}, N, N, N]$, and thus, in this case, $w_1 = \frac{x}{N},\ w_2 = \frac{y}{N},\ w_3 = \frac{z}{N}$. Afterwards, there are two possible steps.
|
||||
|
||||
\begin{enumerate}
|
||||
\item The first option is to purely fit a polynomial to the data of each block. That is, find a polynomial of degree $N-1$ and of dimension $N$ where each $Block_{w_1,w_2,w_3,...}[\ x_1,\ x_2,\ x_3,\ \dots \ ]$ will correspond to some $P(\ x_1,\ x_2,\ x_3,\ \dots,\ x_n)$. The output will be the coefficients of the new polynomial.
|
||||
\item The second option is to attempt to create a polynomial of degree $N-1$ and of dimension $N$ where its coefficients match first $N$ terms of the Taylor Polynomial of $cos(x_1+x_2+x_3+\dots +x_n)$. The coefficients of the new polynomial will attempt to as close to the Taylor Polynomial. The output will be the coefficients of the new polynomial along with a separate function, its usage explained later in the methodology.
|
||||
\end{enumerate}
|
||||
|
||||
\noindent An $N$ dimensional Discrete Fourier Transform (DFT) will now be performed on these blocks. The output is the first $k$ coefficients, where $k$ is determined when the sum of a sufficient $k$ coefficients is greater than 90\% of the convergence of the $N$ dimensional Fourier Series. The 'first' components will be determined by a counting method discussed later.\\
|
||||
\newline
|
||||
Now, these coefficients corresponding to each $Block_{w_1,w_2,w_3,...}$ will be flattened to 2 dimensions. A Discrete Cosine Transform (DCT) will now be applied onto these coefficients, with the rounding threshold higher, for the sake of precision on coefficients.\\
|
||||
\newline
|
||||
The algorithm is now complete. The final products will include: a 2 dimensional DCT of the coefficients of an $N$ dimensional DFT, function for each block. The raveling process will be standard for a given dimensional size, so this needs not be stored.
|
||||
\end{adjustwidth}
|
||||
|
||||
\pagebreak
|
||||
|
||||
\section{Changing Dimensions}
|
||||
|
||||
Firstly, the video is turned into a basic 3 dimensions. This is done by stacking the Frame and RGB dimensions and swapping the Y Pixel and X Pixel to make it more intuitively oriented. The new form becomes: \[ \left[ {\begin{array}{ccc} X Pixel & Y Pixel & Frame+RGB \end{array}} \right] \]
|
||||
That is to say, $[\ x,\ y,\ 3f\ ]$, $[\ x,\ y,\ 3f+1\ ]$, $[\ x,\ y,\ 3f+2\ ]$ would lie in frame $f$, and represent the R, G, and B values, respectively. From here, we can start slicing the data in certain ways to obtain our desired block dimension.
|
||||
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
\includegraphics[width=2in]{images/RGB.png}
|
||||
\caption{Visualization of flattened video data.}
|
||||
\end{figure}
|
||||
|
||||
\subsection{3-Dimensional Block}
|
||||
|
||||
\begin{adjustwidth}{.5in}{}
|
||||
To obtain 3-Dimensional blocks, in this case, we simply can just extract cubes from the already flattened video data. (See Figure 2.) This arises in a data format of $[\frac{x}{N},\frac{y}{N},\frac{z}{N}, N, N, N]$. In this algorithm, $N=6$ was chosen.
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
\includegraphics[width=3in]{images/3DBlocks.png}
|
||||
\caption{3D Blocked Video Data}
|
||||
\end{figure}
|
||||
|
||||
\end{adjustwidth}
|
||||
|
||||
\subsection{4-Dimensional Block}
|
||||
To obtain 4-Dimensional blocks, in this case, we extract a $NxNxN$ cube and then take $N$ cubes downward. (See Figure 3.) This arises in a data format of $[\frac{x}{N},\frac{y}{N^2},\frac{z}{N}, N, N, N, N]$. In this algorithm, $N=6$ was chosen.
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
\includegraphics[width=3in]{images/4DBlocks.png}
|
||||
\caption{4D Blocked Video Data}
|
||||
\end{figure}
|
||||
|
||||
\section{Polynomial Fitting}
|
||||
There are two potential outputs of polynomial fitting. FINISH
|
||||
\subsection{Pure Polynomial Fitting}
|
||||
The given data $D$ is in format: \[ \left[ \begin{array}{ccccc} x_1 & x_2 & x_3 & \dots & x_n \end{array} \right] \]
|
||||
Where its size is $(m+1,\ m+1,\, m+1,\ \dots,\ m+1)$. To find an n-dimensional polynomial of degree m, all that is necessary is find a solution to this system of linear equations: \
|
||||
\[ \left[ \begin{array}{ccccc}
|
||||
\vec{e_1}^{\vec{e_1}} & \vec{e_1}^{\vec{e_2}} & \vec{e_1}^{\vec{e_3}} & \dots & \vec{e_1}^{\vec{e_{max}}}\\
|
||||
\vec{e_2}^{\vec{e_1}} & \vec{e_2}^{\vec{e_2}} & \vec{e_2}^{\vec{e_3}} & \dots & \vec{e_2}^{\vec{e_{max}}}\\
|
||||
\vec{e_3}^{\vec{e_1}} & \vec{e_3}^{\vec{e_2}} & \vec{e_3}^{\vec{e_3}} & \dots & \vec{e_3}^{\vec{e_{max}}}\\
|
||||
\vdots & \vdots & \vdots & \vdots & \vdots \\
|
||||
\vec{e_{max}}^{\vec{e_1}} & \vec{e_{max}}^{\vec{e_2}} & \vec{e_{max}}^{\vec{e_3}} & \dots & \vec{e_{max}}^{\vec{e_{max}}}
|
||||
\end{array} \right]
|
||||
\left[ \begin{array}{c} a_1 \\ a_2 \\ a_3 \\ \vdots \\ a_{max} \end{array} \right] =
|
||||
\left[ \begin{array}{c} D[\vec{e_1}] \\ D[\vec{e_2}] \\ D[\vec{e_3}] \\ \vdots \\ D[\vec{e_{max}}] \end{array} \right]\]
|
||||
Thus, to find the coefficients, all that is necessary is to compute:
|
||||
\[ {\left[ \begin{array}{ccccc}
|
||||
\vec{e_1}^{\vec{e_1}} & \vec{e_1}^{\vec{e_2}} & \vec{e_1}^{\vec{e_3}} & \dots & \vec{e_1}^{\vec{e_{max}}}\\
|
||||
\vec{e_2}^{\vec{e_1}} & \vec{e_2}^{\vec{e_2}} & \vec{e_2}^{\vec{e_3}} & \dots & \vec{e_2}^{\vec{e_{max}}}\\
|
||||
\vec{e_3}^{\vec{e_1}} & \vec{e_3}^{\vec{e_2}} & \vec{e_3}^{\vec{e_3}} & \dots & \vec{e_3}^{\vec{e_{max}}}\\
|
||||
\vdots & \vdots & \vdots & \vdots & \vdots \\
|
||||
\vec{e_{max}}^{\vec{e_1}} & \vec{e_{max}}^{\vec{e_2}} & \vec{e_{max}}^{\vec{e_3}} & \dots & \vec{e_{max}}^{\vec{e_{max}}}
|
||||
\end{array} \right]}^{-1}
|
||||
\left[ \begin{array}{c} D[\vec{e_1}] \\ D[\vec{e_2}] \\ D[\vec{e_3}] \\ \vdots \\ D[\vec{e_{max}}] \end{array} \right]\]
|
||||
|
||||
\noindent Thus, $a_1,\ a_2,\ a_3, \dots,\ a_3$ has now been found.
|
||||
|
||||
\subsection{Cosine Taylor Polynomial Fitting}
|
||||
|
||||
\end{document}
|
||||
BIN
Compression/Blocks.blend
Normal file
BIN
Compression/Blocks.blend
Normal file
Binary file not shown.
BIN
Compression/RGB.png
Normal file
BIN
Compression/RGB.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
263
Compression/compress.py
Normal file
263
Compression/compress.py
Normal file
@ -0,0 +1,263 @@
|
||||
import math
|
||||
import time
|
||||
import sys
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
import scipy.linalg as spla
|
||||
from functools import reduce
|
||||
from os import system
|
||||
from PIL import Image
|
||||
|
||||
def read_video(limit = -1):
|
||||
video = []
|
||||
cap = cv.VideoCapture('D:/Videos/test.mkv')
|
||||
frame_num = 0
|
||||
while cap.isOpened():
|
||||
if limit == frame_num:
|
||||
break
|
||||
ret, frame = cap.read()
|
||||
video.append(frame)
|
||||
system('cls')
|
||||
print("Loading video: {:.2f}%".format(100*frame_num/limit))
|
||||
frame_num += 1
|
||||
return video
|
||||
|
||||
def change_dimension(data, dim):
|
||||
'''
|
||||
Video data is in form [Frame][Y Pixel][X Pixel][RGB]
|
||||
Maximum size should be 10, but smaller is better.
|
||||
Eventually, all dimensional changing should be done in C, programmed
|
||||
specifically for each dimension.
|
||||
'''
|
||||
def cubify(data, s):
|
||||
c = tuple(np.array(data.shape)//s)
|
||||
cubed = np.zeros(tuple(list(c)+[s]*len(c)), dtype=int)
|
||||
trim = [slice(0,s)]
|
||||
def permute(n, dim=[]):
|
||||
if n == len(c):
|
||||
slice_ind = [slice(dim[i]*s, (dim[i]+1)*s) for i in range(n)]
|
||||
cubed[tuple(dim)] = data[tuple(slice_ind)]
|
||||
else:
|
||||
for x in range(c[n]):
|
||||
permute(n+1, dim+[x])
|
||||
permute(0)
|
||||
|
||||
return cubed
|
||||
|
||||
if dim not in [3,4]:
|
||||
raise Exception("Not an available target dimension!")
|
||||
|
||||
if dim == 3:
|
||||
# Outer Form: [X Block][Y Block][Z Block]
|
||||
# Inner Form: [X Pixel][Y Pixel][Frame+RGB] Size: 6
|
||||
s = 6
|
||||
blocks = np.swapaxes(np.concatenate(data, axis=2), 0, 1)
|
||||
blocks = cubify(blocks, s)
|
||||
elif dim == 4:
|
||||
# Outer Form [X Block][Y Block][Z Block]
|
||||
# Inner Form [Psuedo-Y Block][X Pixel][Y Pizel][Frame+RGB] Size: 6
|
||||
s = 6
|
||||
blocks = change_dimension(data, 3)
|
||||
c = list(blocks.shape)[:3]
|
||||
c[2] = c[2]//s
|
||||
cubed = np.zeros(tuple(c+[s]*4), dtype=int)
|
||||
for x in range(c[0]):
|
||||
for y in range(c[1]):
|
||||
for z in range(c[2]):
|
||||
arr = np.concatenate(blocks[x:x+1][0][y:y+1,s*z:s*(z+1)])
|
||||
cubed[x,y,z] = arr
|
||||
blocks = cubed
|
||||
|
||||
return blocks
|
||||
|
||||
def permutations(arr):
|
||||
'''
|
||||
The input array will carry possible permutations.
|
||||
'''
|
||||
final = []
|
||||
def permute(n, items=[]):
|
||||
if n == len(arr):
|
||||
final.append(items)
|
||||
else:
|
||||
for x in arr[n]:
|
||||
permute(n+1, items+[x])
|
||||
permute(0)
|
||||
return final
|
||||
|
||||
def pure_polynomial_fit(blocks, dim): # RESIZE TO 2 PI !!!!!!#
|
||||
'''
|
||||
A polynomial of P(n-1) is generated with an n dimensional block,
|
||||
by calculating the a system of n equations, solved through LU
|
||||
decomposition.
|
||||
'''
|
||||
def permute(c, n, dim=[]):
|
||||
if n == len(c):
|
||||
d = tuple(dim)
|
||||
b = blocks[d].flatten()[::-1]
|
||||
pb = p_inv.dot(b)
|
||||
y = spla.solve_triangular(l, pb, lower=True, check_finite=False)
|
||||
x = spla.solve_triangular(u, y, check_finite=False)
|
||||
block_polynomials[d] = x
|
||||
if np.sum(dim[1:]) == 0:
|
||||
system('cls')
|
||||
print("Fit Poly Block {:.2f}%".format(100*dim[0]/c[0]))
|
||||
else:
|
||||
for x in range(c[n]):
|
||||
permute(c, n+1, dim+[x])
|
||||
|
||||
degree = blocks.shape[-1] - 1
|
||||
deg_perm = permutations(dim*[list(reversed(range(degree+1)))])
|
||||
# Scale the coordinate system from 0 to 2pi, for preparation of DFT.
|
||||
block_coord_perm = (2*math.pi/(degree+1)) * deg_perm[:]
|
||||
|
||||
mat_size = int(math.pow(degree + 1, dim))
|
||||
a = np.zeros((mat_size, mat_size), dtype=np.uint64)
|
||||
for i,perm in enumerate(block_coord_perm):
|
||||
a[i] = np.prod(np.power(perm, deg_perm), axis=1, dtype=np.uint64)
|
||||
|
||||
p, l, u = spla.lu(a)
|
||||
p_inv = np.linalg.inv(p)
|
||||
poly_shape = list(blocks.shape[:-dim]) + [mat_size]
|
||||
block_polynomials = np.zeros(tuple(poly_shape), dtype=np.float64)
|
||||
permute(blocks.shape[:-dim], 0)
|
||||
|
||||
return block_polynomials
|
||||
|
||||
|
||||
def trig_taylor_fit(block):
|
||||
'''
|
||||
Assume the polynomial will be a n-dimensional taylor polynomial,
|
||||
calculate a polynomial regression that will represent the inputs.
|
||||
'''
|
||||
pass
|
||||
|
||||
def nd_dft(poly, dim):
|
||||
'''
|
||||
This function calculates a N-dimensional Discrete Fourier Transform,
|
||||
specifically where f(t) is a polynomial.
|
||||
'''
|
||||
def get_integral_mat(n, x, zero, imag):
|
||||
'''
|
||||
Matrix represents T: P -> K, where P,K have basis' respectively:
|
||||
P: x^n, x^(n-1), x^(n-2), ..., c, ix^n, ix^(n-1), ix^(n-2), ..., ic
|
||||
K: c, 1/k, 1/k^2, ..., 1/k^n, ic, i/k, i/k^2, ..., i/k^n
|
||||
|
||||
This function returns a matrix to calculate the one-dimensional
|
||||
integral. If the argument zero is true, the function will return
|
||||
a matrix assuming the definite integral is from 0.
|
||||
'''
|
||||
mat_rr, mat_ri, mat_ir, mat_ii = [], [], [], []
|
||||
|
||||
def get_mat_part(zero_row_cond, neg_cond):
|
||||
mat_part = []
|
||||
for row in range(n+1):
|
||||
if row % 2 == zero_row_cond:
|
||||
mat_part.append([0]*(n+1))
|
||||
continue
|
||||
else:
|
||||
row_vec = []
|
||||
|
||||
for col in range(n+1):
|
||||
x_pow = n-col-row
|
||||
if x_pow < 0:
|
||||
row_vec.append(0)
|
||||
elif x_pow == 0 and zero:
|
||||
row_vec.append(0)
|
||||
else:
|
||||
neg = -1 if (row - neg_cond) % 4 == 0 else 1
|
||||
const = math.factorial(n-col)/math.factorial(n-col-row)
|
||||
row_vec.append(neg*const*math.pow(x, n-col-row))
|
||||
mat_part.append(row_vec)
|
||||
return np.array(mat_part, dtype=np.float64)
|
||||
|
||||
mat_r = np.concatenate([get_mat_part(0, 3), get_mat_part(1, 2)])
|
||||
if imag:
|
||||
mat_i = np.concatenate([get_mat_part(1, 0), get_mat_part(0, 3)])
|
||||
return np.concatenate([mat_r, mat_i], axis=1)
|
||||
else:
|
||||
return mat_r
|
||||
|
||||
def get_mono_mats(block):
|
||||
rind, iind = np.nonzero(rblock), np.nonzero(iblock)
|
||||
rmono_a, imono_a = rblock[rind], iblock[iind]
|
||||
rmono_deg = np.subtract(deg, np.array(deg_perm)[rind].transpose())
|
||||
imono_deg = np.subtract(2*deg+1, np.array(deg_perm)[iind].transpose())
|
||||
|
||||
mono_count = len(rmono_a) + len(imono_a)
|
||||
mono_mats = np.zeros((dim, mono_count, 2*deg+2))
|
||||
for x in range(dim):
|
||||
mono_deg = np.concatenate([rmono_deg, imono_deg], axis=1)
|
||||
mono_mat[x][np.arange(mono_count), mono_deg[x]]
|
||||
|
||||
return mono_mats
|
||||
|
||||
def precompute_integrals(k_max, dim, degree):
|
||||
'''
|
||||
This function returns all possible combinations of monomial
|
||||
integrals precomputed for all 'k' until k_max excluding k = 0.
|
||||
'''
|
||||
integral_k = np.zeros((degree, k_max-1), dtype=np.float64)
|
||||
mat = get_integral_mat(degree, 2*math.pi, True, False)
|
||||
k_col = np.arange(1, k_max).reshape((k_max-1, 1))
|
||||
k_pow = np.power(k_col, -np.arange(1, degree+2).astype('float64'))
|
||||
k_b = np.concatenate([k_pow, 1j*k_pow], axis=1).transpose()
|
||||
|
||||
mono_integrals = mat.transpose().dot(k_b)
|
||||
# Offset by degree for deg_perm to fit basis x^n, x^(n-1) ... 1.
|
||||
deg_perm = permutations(dim*[list(range(degree+1))])
|
||||
k_perm = magnitude_spiral(dim*[list(range(1, k_max))])
|
||||
poly_integrals = []
|
||||
for deg in deg_perm:
|
||||
k_perm_prod = []
|
||||
for k_vec in k_perm:
|
||||
k_perm_prod.append(np.prod(mono_integrals[deg, k_vec]))
|
||||
poly_integrals.append(k_perm_prod)
|
||||
|
||||
return np.array(poly_integrals)
|
||||
|
||||
def magnitude_spiral(dim, k_max):
|
||||
|
||||
k_perm = permutations(dim*[list(range(-k_max, k_max+1))])
|
||||
k_vecs = {}
|
||||
for k_vec in k_perm:
|
||||
mag = np.linalg.norm(k_vec)
|
||||
try:
|
||||
k_vecs[mag].append(k_vec)
|
||||
except KeyError:
|
||||
k_vecs[mag] = [k_vec]
|
||||
k_vec_sort = {}
|
||||
for mag in list(sorted(k_vecs.keys())):
|
||||
k_vec_sort[mag] = sorted(k_vecs[mag], key=lambda x: list(np.abs(x)))
|
||||
|
||||
return np.concatenate(list(k_vec_sort.values()))
|
||||
|
||||
deg = int(math.sqrt(poly.shape[-1], 1/dim)) - 1
|
||||
|
||||
# In form [Degree Permutation, K permutation]
|
||||
poly_integrals = precompute_integrals(int(math.pow(1000, 1/deg)), dim, deg)
|
||||
|
||||
|
||||
###### FINISH LOOP
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
C_DIM = 4
|
||||
|
||||
video = np.array(read_video(50))
|
||||
vid_blocks = change_dimension(video, C_DIM)
|
||||
block_poly = np.round(pure_polynomial_fit(vid_blocks, C_DIM), 5)
|
||||
|
||||
print(video_blocks[0])
|
||||
c_k = []
|
||||
#for poly in block_polynomials:
|
||||
|
||||
|
||||
#img = Image.fromarray(video[1000])
|
||||
#img.save('D:/Videos/test.png')
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
x
Reference in New Issue
Block a user