Image 高效的livewire算法
我使用的是给定的livewire算法。该算法给出的结果如下: 但它的真正问题是,对于大图像来说,速度非常慢。我需要的图像工作的代码是RGB 4032 × 3024如此大的图像大大减慢了代码的速度。我知道有一些高效的代码可以有效地完成这个过程。谁能给我指一下正确的方向吗?这是我的OpenCV代码Image 高效的livewire算法,image,algorithm,opencv,image-processing,Image,Algorithm,Opencv,Image Processing,我使用的是给定的livewire算法。该算法给出的结果如下: 但它的真正问题是,对于大图像来说,速度非常慢。我需要的图像工作的代码是RGB 4032 × 3024如此大的图像大大减慢了代码的速度。我知道有一些高效的代码可以有效地完成这个过程。谁能给我指一下正确的方向吗?这是我的OpenCV代码 #include <opencv2/opencv.hpp> #include <opencv2/core/core.hpp> #include <opencv2/highg
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <cstdio>
#include <queue>
#define CV_BGR2GRAY cv::COLOR_BGRA2GRAY
using namespace cv;
const double inf = 0x3f3f3f3f3f;
Mat img, img_gray, img_value, fz, fg, I, pre, cost, vis, G, img_draw, in_que, skip, img_canny;
bool g_flag;
Point start;
void Mat_init(){
I.create(img.rows, img.cols, CV_64FC2);
G.create(img.rows, img.cols, CV_64FC1);
fg.create(img.rows, img.cols, CV_64FC1);
pre.create(img.rows, img.cols, CV_32SC2);
cost.create(img.rows, img.cols, CV_64FC1);
vis.create(img.rows, img.cols, CV_8UC1);
fz.create(img.rows, img.cols, CV_64FC1);
in_que.create(img.rows, img.cols, CV_8UC1);
skip.create(img.rows, img.cols, CV_8UC1);
}
double getcost(Point p, Point q, bool flag){
double Ixp = I.at<Vec2d>(p.y, p.x)[0];
double Iyp = I.at<Vec2d>(p.y, p.x)[1];
double Ixq = I.at<Vec2d>(q.y, q.x)[0];
double Iyq = I.at<Vec2d>(q.y, q.x)[1];
double fZ = 0.0, fG = 0.0, fD = 0.0;
fZ = fz.at<uchar>(q.y, q.x);
fG = fg.at<double>(q.y, q.x);
double judge = 0;
judge = Iyp * (q.x - p.x) + (-Ixp) * (q.y - p.y);
double dp = 0.0, dq = 0.0;
// q - p
if (judge >= 0){
dp = Iyp * (q.x - p.x) + (-Ixp) * (q.y - p.y);
dq = (q.x - p.x) * Iyq + (q.y - p.y) * (-Ixq);
}
// p - q
else{
dp = Iyp * (p.x - q.x) + (-Ixp) * (p.y - q.y);
dq = (p.x - q.x) * Iyq + (p.y - q.y) * (-Ixq);
}
if (!flag){
dp /= sqrt(2);
dq /= sqrt(2);
}
double pi = acos(-1.0);
fD = (acos(dp) + acos(dq)) / pi;
if (flag)
fG /= sqrt(2); // vertical or horizontal neighbor
double ans = 0.43 * fZ + 0.43 * fD + 0.14 * fG;
return ans;
}
struct P{
double first;
Point second;
P(){}
P(double a,Point b){
first = a;
second = b;
}
bool operator > (const P &b) const{
return first > b.first;
}
bool operator < (const P &b) const{
return first < b.first;
}
};
void find_min_path(Point start){
int dir_x[] = {1, 0, -1, 0, 1, 1, -1, -1};
int dir_y[] = {0, 1, 0, -1, 1, -1, 1, -1};
vis.setTo(0);
cost.setTo(inf);
in_que.setTo(0);
skip.setTo(0);
cost.at<double>(start.y, start.x) = 0;
in_que.at<uchar>(start.y, start.x) = 1;
std::priority_queue < P, std::vector<P>, std::greater<P> > que;
que.push(P(0, start));
while (!que.empty()){
P cur = que.top();
que.pop();
Point p = cur.second;
in_que.at<uchar>(p.y, p.x) = 0;
if (skip.at<uchar>(p.y, p.x) == 1)
continue;
vis.at<uchar>(p.y, p.x) = 1;
for (int i = 0; i < 8; i++){
int tx = p.x + dir_x[i];
int ty = p.y + dir_y[i];
if (tx < 0 || tx >= img.cols || ty < 0 || ty >= img.rows)
continue;
if (vis.at<uchar>(ty, tx) == 1)
continue;
Point q = Point(tx, ty);
double tmp;
if (i <= 3){
tmp = cost.at<double>(p.y, p.x) + getcost(p, q, true);
}
else{
tmp = cost.at<double>(p.y, p.x) + getcost(p, q, false);
}
if (in_que.at<uchar>(q.y, q.x) == 1 && tmp < cost.at<double>(q.y, q.x)){
skip.at<uchar>(q.y, q.x) = 1;
continue;
}
if (in_que.at<uchar>(q.y, q.x) == 0){
cost.at<double>(q.y, q.x) = tmp;
pre.at<Vec2i>(q.y, q.x)[0] = p.x;
pre.at<Vec2i>(q.y, q.x)[1] = p.y;
in_que.at<uchar>(q.y, q.x) = 1;
que.push(P(cost.at<double>(q.y, q.x), q));
}
}
}
}
void onMouse(int event, int x, int y, int flags, void *param){
if (event == EVENT_LBUTTONDOWN){
start = Point(x, y);
g_flag = true;
find_min_path(start);
img.copyTo(img_draw);
imshow("example", img_draw);
}
else if (event == EVENT_MOUSEMOVE && g_flag){
img.copyTo(img_draw);
Point cur = Point(x, y);
Point tmp;
while (cur != start){
tmp = Point(pre.at<Vec2i>(cur.y, cur.x)[0], pre.at<Vec2i>(cur.y, cur.x)[1]);
line(img_draw, cur, tmp, Scalar(0, 255, 0), 2);
if (tmp == start) break;
cur = tmp;
}
imshow("example", img_draw);
}
else if (event == EVENT_LBUTTONUP){
g_flag = false;
img.copyTo(img_draw);
imshow("example", img_draw);
}
}
int main(){
std::string filepath = "/Users/vedanshu/Desktop/test.png";
namedWindow("example");
img = imread(filepath);
Mat_init();
cvtColor(img, img_gray, CV_BGR2GRAY); // Convert the image to grayscale (using the function cvtColor)
img_gray.copyTo(img_value);
GaussianBlur(img_value, img_value, Size(3, 3), 0, 0, BORDER_DEFAULT); // First, we blur the image with a filter of kernel size 3
Canny(img_gray, img_canny, 50, 100); // Second, we apply the OpenCV function Canny
//Calculating laplacian zero-crossing binary feature, fz
for (int i = 0; i < img.rows; i++){
for (int j = 0; j < img.cols; j++){
if (img_canny.at<uchar>(i, j) == 255) fz.at<uchar>(i, j) = 0;
else fz.at<uchar>(i, j) = 1;
}
}
//Calculating Ix unit vector
for (int i = 0; i < img.rows; i++){
for (int j = 0; j < img.cols - 1; j++){
I.at<Vec2d>(i, j)[0] = (img_value.at<uchar>(i, j + 1) - img_value.at<uchar>(i, j)) / 255.0;
}
I.at<Vec2d>(i, img.cols - 1)[0] = I.at<Vec2d>(i, img.cols - 2)[0];
}
//Calculating Iy unit vector
for (int j = 0; j < img.cols; j++){
for (int i = 0; i < img.rows - 1; i++){
I.at<Vec2d>(i, j)[1] = (img_value.at<uchar>(i + 1, j) - img_value.at<uchar>(i, j)) / 255.0;
}
I.at<Vec2d>(img.rows - 1, j)[1] = I.at<Vec2d>(img.rows - 2, j)[1];
}
double max_G = 0.0;
// If Ix and Iy represent the partials of an image I in x and y respectively, then the gradient magnitude G is approximated with
// G = sqrt(Ix^2 + Iy^2)
for (int i = 0; i < I.rows; i++){
for (int j = 0; j < I.cols; j++){
G.at<double>(i, j) = sqrt(I.at<Vec2d>(i, j)[0] * I.at<Vec2d>(i, j)[0] + I.at<Vec2d>(i, j)[1] * I.at<Vec2d>(i, j)[1]);
max_G = max(max_G, G.at<double>(i, j));
}
}
//Calculating the gradient component function
for (int i = 0; i < fg.rows; i++){
for (int j = 0; j < fg.cols; j++){
fg.at<double>(i, j) = 1.0 - G.at<double>(i, j) / max_G;
}
}
std::cout << "calculate of fz and fg completed!" << std::endl;
setMouseCallback("example", onMouse, 0);
imshow("example", img);
waitKey(0);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义CV\u bgr2灰色CV::颜色\u BGRA2GRAY
使用名称空间cv;
const double inf=0x3f3f;
Mat img、img_gray、img_value、fz、fg、I、pre、cost、vis、G、img_draw、in_que、skip、img_canny;
布尔古旗;
起点;
void Mat_init(){
I.创建(img.rows、img.cols、CV_64FC2);
G.创建(img.rows、img.cols、CV_64FC1);
fg.创建(img.rows、img.cols、CV_64FC1);
预创建(img.rows、img.cols、CV_32SC2);
创建成本(img.rows、img.cols、CV_64FC1);
创建视图(img.rows、img.cols、CV_8UC1);
创建(img.rows、img.cols、CV_64FC1);
在q.create中(img.rows、img.cols、CV_8UC1);
跳过创建(img.rows、img.cols、CV_8UC1);
}
double getcost(点p、点q、布尔标志){
双Ixp=I.at(p.y,p.x)[0];
双Iyp=I.at(p.y,p.x)[1];
双Ixq=I.at(q.y,q.x)[0];
双Iyq=I.at(q.y,q.x)[1];
双fZ=0.0,fG=0.0,fD=0.0;
fZ=fZ.at(q.y,q.x);
fG=fG.at(q.y,q.x);
双重判断=0;
法官=Iyp*(q.x-p.x)+(Ixp)*(q.y-p.y);
双dp=0.0,dq=0.0;
//q-p
如果(判断>=0){
dp=Iyp*(q.x-p.x)+(-Ixp)*(q.y-p.y);
dq=(q.x-p.x)*Iyq+(q.y-p.y)*(-Ixq);
}
//p-q
否则{
dp=Iyp*(p.x-q.x)+(-Ixp)*(p.y-q.y);
dq=(p.x-q.x)*Iyq+(p.y-q.y)*(-Ixq);
}
如果(!标志){
dp/=sqrt(2);
dq/=sqrt(2);
}
双pi=acos(-1.0);
fD=(acos(dp)+acos(dq))/pi;
国际单项体育联合会(旗)
fG/=sqrt(2);//垂直或水平相邻
双ans=0.43*fZ+0.43*fD+0.14*fG;
返回ans;
}
结构P{
双优先;
第二点;
P(){}
P(双a点,b点){
第一个=a;
第二个=b;
}
布尔运算符>(常数P&b)常数{
返回优先>b优先;
}
布尔运算符<(常数P&b)常数{
先返回,std::greater>que;
推(P(0,开始));
而(!que.empty()){
P cur=que.top();
que.pop();
点p=当前秒;
(p.y,p.x)=0;
如果(跳过(p.y,p.x)==1)
继续;
视在(p.y,p.x)=1;
对于(int i=0;i<8;i++){
int tx=p.x+dir_x[i];
int ty=p.y+dir_y[i];
如果(tx<0 | | tx>=img.cols | | ty<0 | | ty>=img.rows)
继续;
如果(相对于(ty,tx)==1)
继续;
点q=点(tx,ty);
双tmp;
如果(i)