在 OpenCV 中使用小波变换进行伤口分割
Wound Segmentation using Wavelet Transform in OpenCV
我们尝试了用于伤口分割的局部直方图方法,但它对所有类型的图像都效果不佳,然后我们教授使用小波变换进行伤口分割。
哪种小波变换适用于伤口分割以及实现它的一些技巧??
有没有比小波变换更好的方法来在所有光照条件下分段缠绕??
我们还尝试了图像聚类,但效果不佳。
这是我们使用的一些测试用例和聚类程序。
#include "cv.h"
#include "highgui.h"
#include <iostream>
void show_result(const cv::Mat& labels, const cv::Mat& centers, int height, int width);
int main(int argc, const char * argv[])
{
cv::Mat image = cv::imread("kmean.jpg");
if ( image.empty() ) {
std::cout << "unable to load an input image\n";
return 1;
}
//cv::cvtColor(image,image,CV_BGR2HSV);
std::cout << "image: " << image.rows << ", " << image.cols << std::endl;
assert(image.type() == CV_8UC3);
cv::imshow("image", image);
cv::Mat reshaped_image = image.reshape(1, image.cols * image.rows);
std::cout << "reshaped image: " << reshaped_image.rows << ", " << reshaped_image.cols << std::endl;
assert(reshaped_image.type() == CV_8UC1);
//check0(image, reshaped_image);
cv::Mat reshaped_image32f;
reshaped_image.convertTo(reshaped_image32f, CV_32FC1, 1.0 / 255.0);
std::cout << "reshaped image 32f: " << reshaped_image32f.rows << ", " << reshaped_image32f.cols << std::endl;
assert(reshaped_image32f.type() == CV_32FC1);
cv::Mat labels;
int cluster_number = 4;
cv::TermCriteria criteria(cv::TermCriteria::COUNT, 100, 1);
cv::Mat centers;
cv::kmeans(reshaped_image32f, cluster_number, labels, criteria, 1, cv::KMEANS_PP_CENTERS, centers);
show_result(labels, centers, image.rows,image.cols);
return 0;
}
void show_result(const cv::Mat& labels, const cv::Mat& centers, int height, int width)
{
std::cout << "===\n";
std::cout << "labels: " << labels.rows << " " << labels.cols << std::endl;
std::cout << "centers: " << centers.rows << " " << centers.cols << std::endl;
assert(labels.type() == CV_32SC1);
assert(centers.type() == CV_32FC1);
cv::Mat rgb_image(height, width, CV_8UC3);
cv::MatIterator_<cv::Vec3b> rgb_first = rgb_image.begin<cv::Vec3b>();
cv::MatIterator_<cv::Vec3b> rgb_last = rgb_image.end<cv::Vec3b>();
cv::MatConstIterator_<int> label_first = labels.begin<int>();
cv::Mat centers_u8;
centers.convertTo(centers_u8, CV_8UC1, 255.0);
cv::Mat centers_u8c3 = centers_u8.reshape(3);
while ( rgb_first != rgb_last ) {
const cv::Vec3b& rgb = centers_u8c3.ptr<cv::Vec3b>(*label_first)[0];
*rgb_first = rgb;
++rgb_first;
++label_first;
}
cv::imshow("tmp", rgb_image);
cv::waitKey();
}
Would-1 背景:(两个集群)
没有背景的 Would-1 :
Would-2 背景:
Would-2 无背景:(三簇)
当我们移除背景时,我们得到了更好的分割,但是为了移除背景,我们使用依赖于手动操作的抓取剪切。所以我们需要一个 kmean-clustering 的替代品来分割图像(或)对上述代码进行一些改进以实现 100% 的成功案例。
那么有没有更好的分割伤口的方法呢??
与其尝试使用传统的小波变换,不如尝试针对目标检测任务调整的 Haar-like 小波,类似于 Viola Jones face detector. This paper by Lienhart et al 中使用的积分图像基础,用于通用目标检测,将是一个好的开始。
从您的示例图像的外观来看,伤口中小像素邻域内的强度变化要高得多,而未受伤的皮肤在小邻域中看起来相当均匀。 Lienhart 论文 应该 能够检测到此类变化 - 您可以将特征输入机器学习设置,或者仅进行手动观察并定义搜索 windows 和相关启发式.
希望对您有所帮助。
我们尝试了用于伤口分割的局部直方图方法,但它对所有类型的图像都效果不佳,然后我们教授使用小波变换进行伤口分割。
哪种小波变换适用于伤口分割以及实现它的一些技巧??
有没有比小波变换更好的方法来在所有光照条件下分段缠绕??
我们还尝试了图像聚类,但效果不佳。
这是我们使用的一些测试用例和聚类程序。
#include "cv.h"
#include "highgui.h"
#include <iostream>
void show_result(const cv::Mat& labels, const cv::Mat& centers, int height, int width);
int main(int argc, const char * argv[])
{
cv::Mat image = cv::imread("kmean.jpg");
if ( image.empty() ) {
std::cout << "unable to load an input image\n";
return 1;
}
//cv::cvtColor(image,image,CV_BGR2HSV);
std::cout << "image: " << image.rows << ", " << image.cols << std::endl;
assert(image.type() == CV_8UC3);
cv::imshow("image", image);
cv::Mat reshaped_image = image.reshape(1, image.cols * image.rows);
std::cout << "reshaped image: " << reshaped_image.rows << ", " << reshaped_image.cols << std::endl;
assert(reshaped_image.type() == CV_8UC1);
//check0(image, reshaped_image);
cv::Mat reshaped_image32f;
reshaped_image.convertTo(reshaped_image32f, CV_32FC1, 1.0 / 255.0);
std::cout << "reshaped image 32f: " << reshaped_image32f.rows << ", " << reshaped_image32f.cols << std::endl;
assert(reshaped_image32f.type() == CV_32FC1);
cv::Mat labels;
int cluster_number = 4;
cv::TermCriteria criteria(cv::TermCriteria::COUNT, 100, 1);
cv::Mat centers;
cv::kmeans(reshaped_image32f, cluster_number, labels, criteria, 1, cv::KMEANS_PP_CENTERS, centers);
show_result(labels, centers, image.rows,image.cols);
return 0;
}
void show_result(const cv::Mat& labels, const cv::Mat& centers, int height, int width)
{
std::cout << "===\n";
std::cout << "labels: " << labels.rows << " " << labels.cols << std::endl;
std::cout << "centers: " << centers.rows << " " << centers.cols << std::endl;
assert(labels.type() == CV_32SC1);
assert(centers.type() == CV_32FC1);
cv::Mat rgb_image(height, width, CV_8UC3);
cv::MatIterator_<cv::Vec3b> rgb_first = rgb_image.begin<cv::Vec3b>();
cv::MatIterator_<cv::Vec3b> rgb_last = rgb_image.end<cv::Vec3b>();
cv::MatConstIterator_<int> label_first = labels.begin<int>();
cv::Mat centers_u8;
centers.convertTo(centers_u8, CV_8UC1, 255.0);
cv::Mat centers_u8c3 = centers_u8.reshape(3);
while ( rgb_first != rgb_last ) {
const cv::Vec3b& rgb = centers_u8c3.ptr<cv::Vec3b>(*label_first)[0];
*rgb_first = rgb;
++rgb_first;
++label_first;
}
cv::imshow("tmp", rgb_image);
cv::waitKey();
}
Would-1 背景:(两个集群)
没有背景的 Would-1 :
Would-2 背景:
Would-2 无背景:(三簇)
当我们移除背景时,我们得到了更好的分割,但是为了移除背景,我们使用依赖于手动操作的抓取剪切。所以我们需要一个 kmean-clustering 的替代品来分割图像(或)对上述代码进行一些改进以实现 100% 的成功案例。
那么有没有更好的分割伤口的方法呢??
与其尝试使用传统的小波变换,不如尝试针对目标检测任务调整的 Haar-like 小波,类似于 Viola Jones face detector. This paper by Lienhart et al 中使用的积分图像基础,用于通用目标检测,将是一个好的开始。
从您的示例图像的外观来看,伤口中小像素邻域内的强度变化要高得多,而未受伤的皮肤在小邻域中看起来相当均匀。 Lienhart 论文 应该 能够检测到此类变化 - 您可以将特征输入机器学习设置,或者仅进行手动观察并定义搜索 windows 和相关启发式.
希望对您有所帮助。