Basic working GUI

This commit is contained in:
2025-10-14 18:14:01 +02:00
parent 15fbb4ae33
commit 90b9b2cb92
9 changed files with 473 additions and 248 deletions
+66 -183
View File
@@ -2,8 +2,12 @@
#include "serfile.h"
#include <QApplication>
#include <QElapsedTimer>
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
#include <QQueue>
#include <opencv2/opencv.hpp>
#include <iostream>
#include <complex>
#include <cmath>
@@ -209,202 +213,81 @@ void fft(std::vector<std::complex<float>> &x, bool inv = false)
}
}
double laplacian(const uint16_t *img, int32_t *out, uint32_t width, uint32_t height)
//光流
void opticalflow()
{
__m256 mean = _mm256_setzero_ps();
__m256 M2 = _mm256_setzero_ps();
uint32_t count = 0;
for(uint32_t y = 1; y < height - 1; y++)
cv::Mat frame1, prvs;
SERFileReader ser;
ser.open("/media/data/indi_2025-09-29/indi_record_2025-09-29@17-29-08.ser");
frame1 = cv::Mat(ser.height(), ser.width(), CV_16U);
ser.getFrame(0, (char*)frame1.data);
cv::Mat frame2(ser.height(), ser.width(), CV_16U);
for(int i=0; i<ser.frameCount(); i++)
{
uint32_t row = (y - 1) * width;
for(uint32_t x = 1; x < width - 17; x += 16)
{
__m256i p0 = _mm256_loadu_si256(reinterpret_cast<__m256i const*>(img + row + x));
__m256i p1 = _mm256_loadu_si256(reinterpret_cast<__m256i const*>(img + (row + width) + x - 1));
__m256i p2 = _mm256_loadu_si256(reinterpret_cast<__m256i const*>(img + (row + width) + x));
__m256i p3 = _mm256_loadu_si256(reinterpret_cast<__m256i const*>(img + (row + width) + x + 1));
__m256i p4 = _mm256_loadu_si256(reinterpret_cast<__m256i const*>(img + (row + width * 2) + x));
ser.getFrame(i, (char*)frame2.data);
if (frame2.empty())
break;
__m256i sumA = _mm256_setzero_si256();
__m256i sumB = _mm256_setzero_si256();
cv::Mat flow(prvs.size(), CV_32FC2);
cv::calcOpticalFlowFarneback(frame1, frame2, flow, 0.5, 3, 40, 3, 5, 1.2, 0);
__m256i a,b;
a = _mm256_cvtepu16_epi32(_mm256_extracti128_si256(p0, 0));
b = _mm256_cvtepu16_epi32(_mm256_extracti128_si256(p0, 1));
sumA = _mm256_add_epi32(sumA, a);
sumB = _mm256_add_epi32(sumB, b);
a = _mm256_cvtepu16_epi32(_mm256_extracti128_si256(p1, 0));
b = _mm256_cvtepu16_epi32(_mm256_extracti128_si256(p1, 1));
sumA = _mm256_add_epi32(sumA, a);
sumB = _mm256_add_epi32(sumB, b);
std::vector<cv::Mat> flow_xy(2);
cv::split(flow, flow_xy);
cv::Mat flow_x = flow_xy[0];
cv::Mat flow_y = flow_xy[1];
a = _mm256_cvtepu16_epi32(_mm256_extracti128_si256(p2, 0));
b = _mm256_cvtepu16_epi32(_mm256_extracti128_si256(p2, 1));
a = _mm256_sll_epi32(a, _mm_set1_epi64x(2));
b = _mm256_sll_epi32(b, _mm_set1_epi64x(2));
sumA = _mm256_sub_epi32(sumA, a);
sumB = _mm256_sub_epi32(sumB, b);
// --- Build map_x and map_y for remapping
cv::Mat map_x(frame1.size(), CV_32FC1);
cv::Mat map_y(frame1.size(), CV_32FC1);
a = _mm256_cvtepu16_epi32(_mm256_extracti128_si256(p3, 0));
b = _mm256_cvtepu16_epi32(_mm256_extracti128_si256(p3, 1));
sumA = _mm256_add_epi32(sumA, a);
sumB = _mm256_add_epi32(sumB, b);
a = _mm256_cvtepu16_epi32(_mm256_extracti128_si256(p4, 0));
b = _mm256_cvtepu16_epi32(_mm256_extracti128_si256(p4, 1));
sumA = _mm256_add_epi32(sumA, a);
sumB = _mm256_add_epi32(sumB, b);
if(out)
{
_mm256_storeu_si256(reinterpret_cast<__m256i*>(out + row + x), sumA);
_mm256_storeu_si256(reinterpret_cast<__m256i*>(out + row + x + 8), sumB);
for (int y = 0; y < frame1.rows; y++) {
for (int x = 0; x < frame1.cols; x++) {
map_x.at<float>(y, x) = x + flow_x.at<float>(y, x);
map_y.at<float>(y, x) = y + flow_y.at<float>(y, x);
}
__m256 af = _mm256_cvtepi32_ps(sumA);
__m256 bf = _mm256_cvtepi32_ps(sumB);
count++;
__m256 delta = _mm256_sub_ps(af, mean);
mean = _mm256_add_ps(mean, _mm256_div_ps(delta, _mm256_set1_ps(static_cast<float>(count))));
__m256 delta2 = _mm256_sub_ps(af, mean);
M2 = _mm256_add_ps(M2, _mm256_mul_ps(delta, delta2));
count++;
delta = _mm256_sub_ps(bf, mean);
mean = _mm256_add_ps(mean, _mm256_div_ps(delta, _mm256_set1_ps(static_cast<float>(count))));
delta2 = _mm256_sub_ps(bf, mean);
M2 = _mm256_add_ps(M2, _mm256_mul_ps(delta, delta2));
//count += 1
//delta = new_value - mean
//mean += delta / count
//delta2 = new_value - mean
//M2 += delta * delta2
}
// --- Warp img1 to align it with img2 using the optical flow
cv::Mat warped;
cv::remap(frame2, warped, map_x, map_y, cv::INTER_LANCZOS4);
cv::imshow("orig", frame2);
cv::imshow("warp", warped);
/*int key = cv::waitKey(3);
if (key == 'q' || key == 27)
break;
continue;*/
// visualization
cv::Mat flow_parts[2];
split(flow, flow_parts);
cv::Mat magnitude, angle, magn_norm;
cv::cartToPolar(flow_parts[0], flow_parts[1], magnitude, angle, true);
cv::normalize(magnitude, magn_norm, 0.0f, 1.0f, cv::NORM_MINMAX);
cv::imshow("mag", magn_norm);
/*angle *= ((1.f / 360.f) * (180.f / 255.f));
//build hsv image
cv::Mat _hsv[3], hsv, hsv8, bgr;
_hsv[0] = angle;
_hsv[1] = cv::Mat::ones(angle.size(), CV_32F);
_hsv[2] = magn_norm;
merge(_hsv, 3, hsv);
hsv.convertTo(hsv8, CV_8U, 255.0);
cvtColor(hsv8, bgr, cv::COLOR_HSV2BGR);
imshow("frame2", bgr);*/
int keyboard = cv::waitKey(30);
if (keyboard == 'q' || keyboard == 27)
break;
}
float mean_2[8];
float M2_2[8];
_mm256_storeu_ps(mean_2, mean);
_mm256_storeu_ps(M2_2, M2);
auto welford_merge = [](uint32_t n, float &mean_1, float mean_2, float &M2_1, float M2_2)
{
uint32_t count = 2 * n;
float delta = mean_2 - mean_1;
float mean = mean_1 + delta * ((float)n / count);
float M2 = M2_1 + M2_2 + delta * delta * n * n / count;
mean_1 = mean;
M2_1 = M2;
};
for(int i = 0; i < 8; i++)
qDebug() << M2_2[i] / count;
welford_merge(count, mean_2[0], mean_2[1], M2_2[0], M2_2[1]);
welford_merge(count, mean_2[2], mean_2[3], M2_2[2], M2_2[3]);
welford_merge(count, mean_2[4], mean_2[5], M2_2[4], M2_2[5]);
welford_merge(count, mean_2[6], mean_2[7], M2_2[6], M2_2[7]);
welford_merge(count * 2, mean_2[0], mean_2[2], M2_2[0], M2_2[2]);
welford_merge(count * 2, mean_2[4], mean_2[6], M2_2[4], M2_2[6]);
welford_merge(count * 4, mean_2[0], mean_2[4], M2_2[0], M2_2[4]);
return (double)M2_2[0] / (count * 8);
}
int main(int argc, char *argv[])
{
SERFileReader ser;
ser.open("/home/nou/.wine/drive_c/indi_2025-10-03/indi_record_2025-10-03@18-24-37.ser");
cv::Rect rect(1024, 1024, 128, 128);
double maxQ = 0;
cv::Mat best;
cv::Mat lap;
cv::Mat first(ser.height(), ser.width(), CV_16U);
cv::Mat img(ser.height(), ser.width(), CV_16U);
cv::Mat out(ser.height(), ser.width(), CV_32S);
cv::Mat imgf32;
ser.getFrame(0, (char*)first.data);
first.convertTo(first, CV_32F);
for(uint32_t i = 0; i < ser.frameCount(); i++)
{
ser.getFrame(i, (char*)img.data);
double var = laplacian((uint16_t*)img.data, (int32_t*)out.data, img.cols, img.rows);
double minval, maxval;
cv::minMaxLoc(out, &minval, &maxval);
out.convertTo(out, CV_32F, 1.0 / (maxval - minval), -minval / (maxval - minval));
qDebug() << "minmax" << minval << maxval;
cv::imshow("lap", out);
img.convertTo(imgf32, CV_32F);
cv::Laplacian(imgf32, lap, CV_32F, 1);
cv::minMaxLoc(lap, &minval, &maxval);
qDebug() << "minmax" << minval << maxval;
cv::Mat stddev;
cv::Mat mean;
cv::meanStdDev(lap, mean, stddev);
lap -= minval;
lap /= (maxval - minval);
cv::imshow("lapcv", lap);
cv::waitKey();
qDebug() << var << std::sqrt(var) << stddev.at<double>(0);
//continue;
return 0;
img.convertTo(imgf32, CV_32F);
cv::Laplacian(imgf32, lap, CV_32F, 1);
cv::Point2d off = cv::phaseCorrelate(first(rect), imgf32(rect));
if(maxQ < stddev.at<double>(0))
{
maxQ = stddev.at<double>(0);
img.copyTo(best);
//qDebug() << "new best" << i;
}
}
cv::imshow("lap", best);
cv::waitKeyEx();
return 0;
cv::Mat img1= cv::imread("/home/nou/Obrázky/astro/moon_2025-10-03/R.tif", cv::IMREAD_GRAYSCALE);
cv::Mat img2= cv::imread("/home/nou/Obrázky/astro/moon_2025-10-03/G.tif", cv::IMREAD_GRAYSCALE);
img1.convertTo(img1, CV_32F);
img2.convertTo(img2, CV_32F);
cv::Point2d point = cv::phaseCorrelate(img1, img2);
cv::Mat img2dst;
cv::Mat t(2, 3, CV_32F);
t.at<float>(0, 0) = 1.0;
t.at<float>(1, 1) = 1.0;
t.at<float>(0, 2) = -point.x;
t.at<float>(1, 2) = -point.y;
cv::warpAffine(img2, img2dst, t, img1.size());
//cv::imshow("img1", img1 / 64.0);
auto diff = img1 - img2dst;
double min, max;
cv::minMaxLoc(diff, &min, &max);
qDebug() << min << max;
cv::imshow("img2", (diff - min) / (32));
cv::imwrite("diff.png", (diff - min) / (max - min) * 255);
cv::imwrite("avg.png", (img1 + img2dst) * 0.5);
cv::minMaxLoc(img1, &min, &max);
qDebug() << min << max;
cv::waitKey();
return 0;
/*QApplication a(argc, argv);
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();*/
return a.exec();
}