我希望能编写一个程序,在夜空照片中识别出星星并加以标记。因为我对数字信号处理还不是很了解,所以想问一下如何实现这个想法。我已经勾画了一份代码草稿:
#include "main.hpp"
using namespace std;
//using namespace cv;
int main(int argc, char *argv[])
{
const char *imageName = (argc >= 2) ? argv[1] : "4.jpg";
int64_t processTime;
cv::Mat imageSource, result1, result2, grayScaledImage;
/// Create and initialize the kerenel matrix
cv::Mat kernelMatrix = (cv::Mat_<char>(3, 3) << 0, -1, 0,
-1, 5, -1,
0, -1, 0);
cout << "Start..." << endl;
if ((argc == 3) && !(strcmp("G", argv[2]))) imageSource = cv::imread(cv::samples::findFile(imageName), cv::IMREAD_GRAYSCALE);
else imageSource = cv::imread(cv::samples::findFile(imageName), cv::IMREAD_COLOR);
/// Check for errors while open
if (imageSource.empty())
{
cerr << "Can't open image [" << imageName << "]" << endl;
exit(EXIT_FAILURE);
}
processTime = cv::getTickCount(); /// Start timer
//img_proc::sharpening(imageSource, result1); /// Process image
cv::cvtColor(imageSource, grayScaledImage, cv::COLOR_BGR2GRAY);
cv::filter2D(grayScaledImage, result1, imageSource.depth(), kernelMatrix); /// Process image
processTime = (cv::getTickCount() - processTime) / cv::getTickFrequency(); /// Stop timer and fix the process time
/// Create windows for pictures
cv::namedWindow("Source image", cv::WINDOW_AUTOSIZE);
cv::namedWindow("Result image (1)", cv::WINDOW_AUTOSIZE);
/// Show images
cv::imshow("Source image", imageSource);
cv::imshow("Result image (1)", result1);
cv::waitKey(0);
/// The second method
processTime = cv::getTickCount(); /// Start timer
cv::Sobel(result1, result2, CV_32F, 1, 0); /// S
processTime = (cv::getTickCount() - processTime) / cv::getTickFrequency(); /// Stop timer and fix the process time
cv::namedWindow("Result image (2)", cv::WINDOW_AUTOSIZE);
cv::imshow("Result image (2)", result2);
cv::waitKey();
double minVal, maxVal;
cv::Mat newMat;
cv::minMaxLoc(result2, &minVal, &maxVal);
result2.convertTo(newMat, CV_8U, (255.0 / (maxVal - minVal)), (-minVal * 255.0 / (maxVal - minVal)));
cv::namedWindow("newmat", cv::WINDOW_AUTOSIZE);
cv::imshow("newmat", newMat);
cv::waitKey();
return 0;
}
因此,我得到了以下图像(左边是初始图像,右边是最终图像):
![result images](https://istack.dev59.com/b3O7v.webp)
H-maxima
的方法。局部极大值可能会给出一些误报,但是对于星星来说,这并不会带来太多痛苦。skimage网站上有很好的文档。此外,如果您是图像处理新手,我建议您选择使用python
+scikit-image
。opencv
文档相当令人失望。 - Piotr Rarus