如何使用opencv在控制点上绘制曲线 [英] how to draw curve on control points using opencv

查看:358
本文介绍了如何使用opencv在控制点上绘制曲线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在控制点上绘制曲线,以便我可以移动曲线来更改颜色,下面是代码,从(附加到您的项目:overhauser.cpp overhauser.hpp和vec3.hpp):



/ move a point,right removed。



  #include< iostream> 
#include< vector>
#include< stdio.h>
#include< functional>
#include< algorithm>
#include< numeric>
#include< cstddef>
#includeopencv2 / opencv.hpp
#include< iostream>
#include< fstream>
#includeoverhauser.hpp

using namespace std;
using namespace cv;

结果;
Mat Img;

int current_color = 0;

vector< cv :: Point2f> pts_red;
vector< cv :: Point2f> pts_green;
vector< cv :: Point2f> pts_blue;

Mat curvesImg;
int selectedPt = -1;

CRSpline * spline_red = 0;
CRSpline * spline_green = 0;
CRSpline * spline_blue = 0;

unsigned char LUT_RED [256];
unsigned char LUT_GREEN [256];
unsigned char LUT_BLUE [256];

//比较函数:
bool mycomp(Point2f p1,Point2f p2)
{
return p1.x< p2.x;
}

float dist(Point2f p1,Point2f p2)
{
return sqrt(p1.x-p2.x)*(p1.x-p2 .x)+(p1.y-p2.y)*(p1.y-p2.y));
}

int findNEarestPt(Point2f pt,float maxDist)
{
vector< Point2f> current_pts_set;

current_color = 0;

if(pt.x> 255& pt.x< 512)
{
current_color = 1;
}

if(pt.x> = 512)
{
current_color = 2;
}

float ptx = pt.x;

switch(current_color)
{
case 0:
current_pts_set = pts_red;
break;
case 1:
current_pts_set = pts_green;
pt.x- = 255;
break;
case 2:
current_pts_set = pts_blue;
pt.x- = 511;
break;
}

float minDist = FLT_MAX;
int ind = -1;
for(int i = 0; i {
float d = dist(pt,current_pts_set [i]);
if(minDist> d)
{
ind = i;
minDist = d;
}
}
if(minDist> maxDist)
{
ind =
}

return ind;
}

float F(float t,float x,CRSpline * spline)
{
vec3 rv = spline-> GetInterpolatedSplinePoint(t);
return x-rv.x;
}

float solveForX(float x,CRSpline * slpine)
{
float a = -1.0f,b = 1.0,c,e = 1e-2 ;
c =(a + b)/ 2;
while((fab(ba)> e)&(F(c,x,slpine)! slpine)* F(c,x,slpine)<0)
{
b = c;
}
else
{
a = c;
}
c =(a + b)/ 2;
}
return c;
}


int ind = -1;

void mouseHandler(int event,int x,int y,int flags,void * param)
{
Point2f m;
m.x = x;
m.y = y;
curvesImg = Scalar(0,0,0);

switch(event)
{
case cv :: EVENT_RBUTTONDOWN:
ind = findNEarestPt(m,5);
if(ind == - 1)
{

} else
{
switch(current_color)
{
case 0:
pts_red.erase(pts_red.begin()+ ind);
break;
case 1:
pts_green.erase(pts_green.begin()+ ind);
break;
case 2:
pts_blue.erase(pts_blue.begin()+ ind);
break;
}
ind = -1;
}
break;

case cv :: EVENT_LBUTTONDOWN:
ind = findNEarestPt(m,5);
if(ind == - 1)
{
switch(current_color)
{
case 0:
pts_red.push_back
selectedPt = pts_red.size() - 1;
break;
case 1:

pts_green.push_back(Point2f(m.x-255.0,m.y));
selectedPt = pts_green.size() - 1;
break;
case 2:
pts_blue.push_back(Point2f(m.x-511,m.y));
selectedPt = pts_blue.size() - 1;
break;
}
} else
{
selectedPt = ind;
}
break;

case cv :: EVENT_MOUSEMOVE:
if(ind!= - 1)
{
switch(current_color)
{
case 0 :
pts_red [selectedPt] .x = mx;
pts_red [selectedPt] .y = m.y;
break;
case 1:
pts_green [selectedPt] .x = m.x-255;
pts_green [selectedPt] .y = m.y;
break;
case 2:
pts_blue [selectedPt] .x = m.x-511;
pts_blue [selectedPt] .y = m.y;
break;
}
}
break;
case cv :: EVENT_LBUTTONUP:
ind = -1;
break;
}

std :: sort(pts_red.begin(),pts_red.end(),mycomp);
if(pts_red.size()> 0)
{
pts_red [pts_red.size() - 1] .x = 255;
pts_red [0] .x = 0;
}

std :: sort(pts_green.begin(),pts_green.end(),mycomp);
if(pts_green.size()> 0)
{
pts_green [pts_green.size() - 1] .x = 255;
pts_green [0] .x = 0;
}

std :: sort(pts_blue.begin(),pts_blue.end(),mycomp);
if(pts_blue.size()> 0)
{
pts_blue [pts_blue.size() - 1] .x = 255;
pts_blue [0] .x = 0;
}

for(int i = 0; i {
circle(curvesImg,pts_red [i] 5,Scalar(0,0,255), - 1,CV_AA);
}

for(int i = 0; i {
circle(curvesImg,Point2f(pts_green [i ] .x + 255,pts_green [i] .y),5,Scalar(0,255,0), - 1,CV_AA);
}

for(int i = 0; i {
circle(curvesImg,Point2f(pts_blue [i ] .x + 511,pts_blue [i] .y),5,Scalar(255,0,0), - 1,CV_AA);
}

if(spline_red){delete spline_red;}
spline_red = new CRSpline();

if(spline_green){delete spline_green;}
spline_green = new CRSpline();

if(spline_blue){delete spline_blue;}
spline_blue = new CRSpline();

for(int i = 0; i {
vec3 v(pts_red [i] .x,pts_red [i] .y,0);
spline_red-> AddSplinePoint(v);
}

for(int i = 0; i {
vec3 v(pts_green [i] .x ,pts_green [i] .y,0);
spline_green-> AddSplinePoint(v);
}

for(int i = 0; i {
vec3 v(pts_blue [i] .x ,pts_blue [i] .y,0);
spline_blue-> AddSplinePoint(v);
}

vec3 rv_last(0,0,0);
if(pts_red.size()> 2)
{
for(int i = 0; i <256; ++ i)
{
float t = solveForX(i,spline_red);
vec3 rv = spline_red-> GetInterpolationSplinePoint(t);
if(rv.y> 255){rv.y = 255;}
if(rv.y< 0){rv.y = 0;}
unsigned char I = char)(rv.y);
LUT_RED [i] = 255-I;
if(i> 0)
{
line(curvesImg,Point(rv.x,rv.y),Point(rv_last.x,rv_last.y),Scalar(0,0,255 ),1);
}
rv_last = rv;
}
}
rv_last = vec3(0,0,0);
if(pts_green.size()> 2)
{
for(int i = 0; i <256; ++ i)
{
float t = solveForX(i,spline_green);
vec3 rv = spline_green-> GetInterpolatedSplinePoint(t);
if(rv.y> 255){rv.y = 255;}
if(rv.y <0){rv.y = 0;}
unsigned char I = char)(rv.y);
LUT_GREEN [i] = 255-I;
if(i> 0)
{
line(curvesImg,Point(rv.x + 255,rv.y),Point(rv_last.x + 255,rv_last.y),Scalar (0,255,0),1);
}
rv_last = rv;
}
}
rv_last = vec3(0,0,0);
if(pts_blue.size()> 2)
{
for(int i = 0; i <256; ++ i)
{
float t = solveForX(i,spline_blue);
vec3 rv = spline_blue-> GetInterpolatedSplinePoint(t);
if(rv.y> 255){rv.y = 255;}
if(rv.y< 0){rv.y = 0;}
unsigned char I = char)(rv.y);
LUT_BLUE [i] = 255-I;
if(i> 0)
{
line(curvesImg,Point(rv.x + 511,rv.y),Point(rv_last.x + 511,rv_last.y),Scalar (255,0,0),1);
}
rv_last = rv;
}

}

int cur_col = 0;

if(m.x> 255&& m.x< 512)
{
cur_col = 1;
}

if(m.x> = 512)
{
cur_col = 2;
}

标量col
switch(cur_col)
{
case 0:
col = Scalar(0,0,255);
break;
case 1:
col = Scalar(0,255,0);
break;
case 2:
col = Scalar(255,0,0);
break;
}
line(curvesImg,Point(0,m.y),Point(curvesImg.cols,m.y),col,1);
line(curvesImg,Point(m.x,0),Point(m.x,curvesImg.rows),col,1);

imshow(Correction curves,curvesImg);

vector< Mat> ch;
cv :: split(Img,ch);
LUT(ch [0],Mat(256,1,CV_8UC1,LUT_BLUE),ch [0]);
LUT(ch [2],Mat(256,1,CV_8UC1,LUT_RED),ch [2]);
LUT(ch [1],Mat(256,1,CV_8UC1,LUT_GREEN),ch [1]);
cv :: merge(ch,result);

imshow(Transformed,result);
}
// ---------------------------------
//
// ---------------------------------
// ===== ==================================================== =======================

int main(int argc,char ** argv)
{

for(int i = 0; i <256; ++ i)
{
LUT_RED [i] = i;
LUT_GREEN [i] = i;
LUT_BLUE [i] = i;
}

namedWindow(Image);
namedWindow(Correction curves);
namedWindow(Transformed);

Img = imread(D:\\ImagesForTest\\\lena.jpg,1);

imshow(Image,Img);

curvesImg = Mat :: zeros(256,768,CV_8UC3);
setMouseCallback(Correction curves,mouseHandler,NULL);
waitKey(0);

getchar();
}


I want to draw curve on control points so that I can move the curve to change the colours , below is the code , getting help from a very well explained answer

const int N=5;      // number of control points (must be >= 4)
float ctrl[N]=      // control points y values initiated with linear function y=x
{           // x value is index*1.0/(N-1)
    0.00,
    0.25,
    0.50,
    0.75,
    1.00,
 };
float correction(float col,float *ctrl,int n)
    {
    float di=1.0/float(n-1);
    int i0,i1,i2,i3;
    float t,tt,ttt;
    float a0,a1,a2,a3,d1,d2;
    // find start control point
    col*=float(n-1);
    i1=col; col-=i1;
    i0=i1-1;
    i2=i1+1; if (i2>=n) i2=n-1;
    i3=i1+2;
    // compute interpolation coefficients
    if (i0>=0) d1=0.5*(ctrl[i2]-ctrl[i0]); else d1=ctrl[i2]-ctrl[i1];
    if (i3< n) d2=0.5*(ctrl[i3]-ctrl[i1]); else d2=ctrl[i2]-ctrl[i1];
    a0=ctrl[i1];
    a1=d1;
    a2=(3.0*(ctrl[i2]-ctrl[i1]))-(2.0*d1)-d2;
    a3=d1+d2+(2.0*(-ctrl[i2]+ctrl[i1]));
    // now interpolate new colro intensity
    t=col; tt=t*t; ttt=tt*t;
    t=a0+(a1*t)+(a2*tt)+(a3*ttt);
    return t;
    }




int main (int argc, const char** argv)
{
Mat input = imread ("E:\\img2.jpg");
Mat input1 = input;
for(int i=0 ; i<input1.rows ; i++)
{
    for (int p=0;p<input1.cols;p++)
    {

        input1.at<cv::Vec3b>(i,p)[0] = 255*correction(input1.at<cv::Vec3b>(i,p)[0]/255.0,ctrl,N);  //B
        input1.at<cv::Vec3b>(i,p)[1] = 255*correction(input1.at<cv::Vec3b>(i,p)[1]/255.0,ctrl,N);  //G
        input1.at<cv::Vec3b>(i,p)[2] = 255*correction(input1.at<cv::Vec3b>(i,p)[2]/255.0,ctrl,N);  //R

    }
}

imshow("image" , input);
waitKey();

}

But the required output is like the curve the program is working , but the curves are not drawing on my screen like below , how to draw them using opencv or other approach So that these lines can play the role of their specific colour in image and with their values , like below right one is the orignal image and left one is the result of changing values through cuves , below curves are the control points per B,G,R

解决方案

This code sketch allows you to edit spline with mouse it uses the files from this link (attach to your project: overhauser.cpp overhauser.hpp and vec3.hpp):

Left mouse button adds/moves a point, right removes.

#include <iostream>
#include <vector>
#include <stdio.h>
#include <functional>
#include <algorithm>
#include <numeric>
#include <cstddef>
#include "opencv2/opencv.hpp"
#include <iostream>
#include <fstream>
#include "overhauser.hpp"

using namespace std;
using namespace cv;

Mat result;
Mat Img;

int current_color=0;

vector<cv::Point2f> pts_red;
vector<cv::Point2f> pts_green;
vector<cv::Point2f> pts_blue;

Mat curvesImg;
int selectedPt=-1;

CRSpline* spline_red = 0;
CRSpline* spline_green = 0;
CRSpline* spline_blue = 0;

unsigned char LUT_RED[256];
unsigned char LUT_GREEN[256];
unsigned char LUT_BLUE[256];

// comparison function:
bool mycomp (Point2f p1, Point2f p2)
{
    return p1.x<p2.x;
}

float dist(Point2f p1,Point2f p2)
{
    return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}

int findNEarestPt(Point2f pt, float maxDist)
{   
    vector<Point2f> current_pts_set;

    current_color=0;

    if(pt.x>255 && pt.x<512)
    {
        current_color=1;
    }

    if(pt.x>=512)
    {
        current_color=2;
    }

    float ptx=pt.x;

    switch(current_color)
    {
    case 0:
        current_pts_set=pts_red;
        break;
    case 1:
        current_pts_set=pts_green;
        pt.x-=255;
        break;
    case 2:
        current_pts_set=pts_blue;
        pt.x-=511;
        break;
    }

    float minDist=FLT_MAX;
    int ind=-1;
    for(int i=0;i<current_pts_set.size();++i)
    {
        float d=dist(pt,current_pts_set[i]);
        if(minDist>d)
        {
            ind=i;
            minDist=d;
        }
    }
    if(minDist>maxDist)
    {
        ind=-1;
    }

    return ind;
}

float F(float t,float x, CRSpline* spline)
{
    vec3 rv = spline->GetInterpolatedSplinePoint(t);
    return x-rv.x;
}

float solveForX(float x,CRSpline* slpine)
{
    float a=-1.0f,b=1.0,c,e=1e-2;
    c=(a+b)/2;
    while( (fabs(b-a)>e) && (F(c,x,slpine)!=0) )
    {
        if (F(a,x,slpine)*F(c,x,slpine)<0)
        {
            b=c;
        }
        else
        {
            a=c;
        }
        c=(a+b)/2;
    }
    return c;
}


int ind=-1;

void mouseHandler(int event, int x, int y, int flags, void* param)
{
    Point2f m;
    m.x=x;
    m.y=y;
    curvesImg=Scalar(0,0,0);

    switch (event)
    {
    case cv::EVENT_RBUTTONDOWN:
        ind=findNEarestPt(m,5);
        if (ind==-1)
        {

        }else
        {
            switch(current_color)
            {
            case 0:
                pts_red.erase(pts_red.begin()+ind);
                break;
            case 1:
                pts_green.erase(pts_green.begin()+ind);
                break;
            case 2:
                pts_blue.erase(pts_blue.begin()+ind);
                break;
            }
            ind=-1;
        }
        break;

    case cv::EVENT_LBUTTONDOWN:
        ind=findNEarestPt(m,5);
        if (ind==-1)
        {
            switch(current_color)
            {
            case 0:
                pts_red.push_back(m);
                selectedPt=pts_red.size()-1;
                break;
            case 1:

                pts_green.push_back(Point2f(m.x-255.0,m.y));
                selectedPt=pts_green.size()-1;
                break;
            case 2:
                pts_blue.push_back(Point2f(m.x-511,m.y));
                selectedPt=pts_blue.size()-1;
                break;
            }
        }else
        {
            selectedPt=ind;
        }
        break;

    case cv::EVENT_MOUSEMOVE:
        if(ind!=-1)
        {
            switch(current_color)
            {
            case 0:
                pts_red[selectedPt].x=m.x;
                pts_red[selectedPt].y=m.y;
                break;
            case 1:
                pts_green[selectedPt].x=m.x-255;
                pts_green[selectedPt].y=m.y;
                break;
            case 2:
                pts_blue[selectedPt].x=m.x-511;
                pts_blue[selectedPt].y=m.y;
                break;
            }
        }
        break;
    case cv::EVENT_LBUTTONUP:
        ind=-1;
        break;
    }

    std::sort(pts_red.begin(),pts_red.end(),mycomp);
    if(pts_red.size()>0)
    {
        pts_red[pts_red.size()-1].x=255;
        pts_red[0].x=0;
    }

    std::sort(pts_green.begin(),pts_green.end(),mycomp);
    if(pts_green.size()>0)
    {
        pts_green[pts_green.size()-1].x=255;
        pts_green[0].x=0;
    }

    std::sort(pts_blue.begin(),pts_blue.end(),mycomp);
    if(pts_blue.size()>0)
    {
        pts_blue[pts_blue.size()-1].x=255;
        pts_blue[0].x=0;
    }

    for(int i=0;i<pts_red.size();++i)
    {
        circle(curvesImg,pts_red[i],5,Scalar(0,0,255),-1,CV_AA);
    }

    for(int i=0;i<pts_green.size();++i)
    {
        circle(curvesImg,Point2f(pts_green[i].x+255,pts_green[i].y),5,Scalar(0,255,0),-1,CV_AA);
    }

    for(int i=0;i<pts_blue.size();++i)
    {
        circle(curvesImg,Point2f(pts_blue[i].x+511,pts_blue[i].y),5,Scalar(255,0,0),-1,CV_AA);
    }

    if (spline_red) {delete spline_red;}
    spline_red = new CRSpline();

    if (spline_green) {delete spline_green;}
    spline_green = new CRSpline();

    if (spline_blue) {delete spline_blue;}
    spline_blue = new CRSpline();

    for (int i=0;i<pts_red.size();++i)
    {
        vec3 v(pts_red[i].x,pts_red[i].y,0);
        spline_red->AddSplinePoint(v);
    }

    for (int i=0;i<pts_green.size();++i)
    {
        vec3 v(pts_green[i].x,pts_green[i].y,0);
        spline_green->AddSplinePoint(v);
    }

    for (int i=0;i<pts_blue.size();++i)
    {
        vec3 v(pts_blue[i].x,pts_blue[i].y,0);
        spline_blue->AddSplinePoint(v);
    }

    vec3 rv_last(0,0,0);
    if(pts_red.size()>2)
    {
        for(int i=0;i<256;++i)
        {
            float t=solveForX(i,spline_red);
            vec3 rv = spline_red->GetInterpolatedSplinePoint(t);
            if(rv.y>255){rv.y=255;}
            if(rv.y<0){rv.y=0;}
            unsigned char I=(unsigned char)(rv.y);
            LUT_RED[i]=255-I;
            if(i>0)
            {
                line(curvesImg,Point(rv.x,rv.y),Point(rv_last.x,rv_last.y),Scalar(0,0,255),1);
            }
            rv_last=rv;
        }
    }
    rv_last=vec3(0,0,0);
    if(pts_green.size()>2)
    {
        for(int i=0;i<256;++i)
        {
            float t=solveForX(i,spline_green);
            vec3 rv = spline_green->GetInterpolatedSplinePoint(t);
            if(rv.y>255){rv.y=255;}
            if(rv.y<0){rv.y=0;}
            unsigned char I=(unsigned char)(rv.y);
            LUT_GREEN[i]=255-I;
            if(i>0)
            {
                line(curvesImg,Point(rv.x+255,rv.y),Point(rv_last.x+255,rv_last.y),Scalar(0,255,0),1);
            }
            rv_last=rv;
        }
    }
    rv_last=vec3(0,0,0);
    if(pts_blue.size()>2)
    {
        for(int i=0;i<256;++i)
        {
            float t=solveForX(i,spline_blue);
            vec3 rv = spline_blue->GetInterpolatedSplinePoint(t);
            if(rv.y>255){rv.y=255;}
            if(rv.y<0){rv.y=0;}
            unsigned char I=(unsigned char)(rv.y);
            LUT_BLUE[i]=255-I;
            if(i>0)
            {
                line(curvesImg,Point(rv.x+511,rv.y),Point(rv_last.x+511,rv_last.y),Scalar(255,0,0),1);
            }
            rv_last=rv;
        }

    }

    int cur_col=0;

    if(m.x>255 && m.x<512)
    {
        cur_col=1;
    }

    if(m.x>=512)
    {
        cur_col=2;
    }

    Scalar col;
    switch(cur_col)
    {
    case 0:
        col=Scalar(0,0,255);
        break;
    case 1:
        col=Scalar(0,255,0);
        break;
    case 2:
        col=Scalar(255,0,0);
        break;
    }
    line(curvesImg,Point(0,m.y),Point(curvesImg.cols,m.y),col,1);
    line(curvesImg,Point(m.x,0),Point(m.x,curvesImg.rows),col,1);

    imshow("Correction curves",curvesImg);  

    vector<Mat> ch;
    cv::split(Img,ch);
    LUT(ch[0],Mat(256,1,CV_8UC1,LUT_BLUE),ch[0]);
    LUT(ch[2],Mat(256,1,CV_8UC1,LUT_RED),ch[2]);
    LUT(ch[1],Mat(256,1,CV_8UC1,LUT_GREEN),ch[1]);
    cv::merge(ch,result);

    imshow("Transformed",result);   
}
// ---------------------------------
// 
// ---------------------------------
//==============================================================================

int main( int argc, char** argv )
{

    for (int i=0;i<256;++i)
    {
        LUT_RED[i]=i;
        LUT_GREEN[i]=i;
        LUT_BLUE[i]=i;
    }

    namedWindow("Image");
    namedWindow("Correction curves");
    namedWindow("Transformed");

    Img=imread("D:\\ImagesForTest\\lena.jpg",1);

    imshow("Image",Img);

    curvesImg=Mat::zeros(256,768,CV_8UC3);
    setMouseCallback("Correction curves", mouseHandler, NULL);
    waitKey(0);

    getchar();
}

这篇关于如何使用opencv在控制点上绘制曲线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆