-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfft_crop_seg
145 lines (131 loc) · 4.19 KB
/
fft_crop_seg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <fftw3.h>
class ImageConverter
{
private:
ros::NodeHandle nh_;
image_transport::ImageTransport it_;
image_transport::Subscriber image_sub_;
fftw_complex *in1, *in2, *out1, *out2;
fftw_plan p1, p2, p3;
bool first_image_received_;
int rows_, cols_;
public:
ImageConverter()
: it_(nh_), first_image_received_(false), rows_(0), cols_(0)
{
image_sub_ = it_.subscribe("/c2i_intensity_image", 10, &ImageConverter::imageCb, this);
}
~ImageConverter()
{
fftw_destroy_plan(p1);
fftw_destroy_plan(p2);
fftw_destroy_plan(p3);
fftw_free(in1);
fftw_free(in2);
fftw_free(out1);
fftw_free(out2);
}
void imageCb(const sensor_msgs::ImageConstPtr& msg)
{
cv_bridge::CvImagePtr cv_ptr;
try
{
cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::TYPE_16UC1);
if (!first_image_received_) {
rows_ = cv_ptr->image.rows;
cols_ = cv_ptr->image.cols;
in1 = fftw_alloc_complex(rows_ * cols_);
in2 = fftw_alloc_complex(rows_ * cols_);
out1 = fftw_alloc_complex(rows_ * cols_);
out2 = fftw_alloc_complex(rows_ * cols_);
p1 = fftw_plan_dft_2d(rows_, cols_, in1, out1, FFTW_FORWARD, FFTW_ESTIMATE);
p2 = fftw_plan_dft_2d(rows_, cols_, in2, out2, FFTW_FORWARD, FFTW_ESTIMATE);
p3 = fftw_plan_dft_2d(rows_, cols_, out2, in2, FFTW_BACKWARD, FFTW_ESTIMATE);
fillInput(cv_ptr->image, in1);
fftw_execute(p1);
for (int i = 0; i < rows_ * cols_; ++i) {
in2[i][0] = out1[i][0];
in2[i][1] = out1[i][1];
}
first_image_received_ = true;
} else {
cv::Mat croppedImage = cropImage(cv_ptr->image, 300, 16);
fillInput(croppedImage, in2);
fftw_execute(p2);
phaseCorrelation();
fftw_execute(p3);
normalizeAndDisplay(in2);
}
}
catch (cv_bridge::Exception& e)
{
ROS_ERROR("cv_bridge exception: %s", e.what());
return;
}
}
cv::Mat cropImage(const cv::Mat &image, int width, int height) {
// Assuming you want to crop to the center
int startX = (image.cols - width) / 2;
int startY = (image.rows - height) / 2;
cv::Rect roi(startX, startY, width, height);
return image(roi);
}
void fillInput(const cv::Mat& img, fftw_complex* input)
{
int index = 0;
for (int i = 0; i < img.rows; ++i) {
for (int j = 0; j < img.cols; ++j) {
input[index][0] = (double)img.at<uint16_t>(i, j);
input[index][1] = 0.0;
index++;
}
}
}
void phaseCorrelation()
{
for (int i = 0; i < rows_ * cols_; ++i) {
double mag1 = sqrt(out1[i][0] * out1[i][0] + out1[i][1] * out1[i][1]);
double mag2 = sqrt(out2[i][0] * out2[i][0] + out2[i][1] * out2[i][1]);
if (mag1 > 0.0 && mag2 > 0.0) {
double phase1 = atan2(out1[i][1], out1[i][0]);
double phase2 = atan2(out2[i][1], out2[i][0]);
out2[i][0] = cos(phase2 - phase1);
out2[i][1] = sin(phase2 - phase1);
} else {
out2[i][0] = out2[i][1] = 0.0;
}
}
}
void normalizeAndDisplay(fftw_complex* output)
{
cv::namedWindow("POC Result", cv::WINDOW_NORMAL);
cv::resizeWindow("POC Result", cols_, rows_);
cv::Mat result(rows_, cols_, CV_8UC1);
cv::Mat tempResult(rows_, cols_, CV_32F);
for (int i = 0; i < rows_ * cols_; ++i) {
double val = sqrt(output[i][0] * output[i][0] + output[i][1] * output[i][1]);
tempResult.at<float>(i / cols_, i % cols_) = val;
}
double minVal, maxVal;
cv::Point minLoc, maxLoc;
cv::minMaxLoc(tempResult, &minVal, &maxVal, &minLoc, &maxLoc);
tempResult.convertTo(result, CV_8UC1, 255.0 / maxVal);
cv::circle(result, maxLoc, 5, cv::Scalar(255), 2);
cv::imshow("POC Result", result);
cv::waitKey(3);
ROS_INFO("Peak correlation at (%d, %d) with value %.2f", maxLoc.x, maxLoc.y, maxVal);
}
};
int main(int argc, char** argv)
{
ros::init(argc, argv, "image_converter");
ImageConverter ic;
ros::spin();
return 0;
}