【头歌 计算机图形学 练习】多边形填充v1.0 (第1关:扫描线填充算法(活动边表AET法) 第2关:边缘填充法 第3关:区域四连通种子填充算法 第4关:区域扫描线种子填充算法)

简介: 【头歌 计算机图形学 练习】多边形填充v1.0 (第1关:扫描线填充算法(活动边表AET法) 第2关:边缘填充法 第3关:区域四连通种子填充算法 第4关:区域扫描线种子填充算法)

前言

不支持学术抄袭,抄袭后果自负,仅供参考学习。

链接: 头歌计算机图形学

第1关:扫描线填充算法(活动边表AET法)

// 评测代码所用头文件-开始
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
// 评测代码所用头文件-结束
#include<GL/freeglut.h>
#include<math.h>
#include<string>
#include <iostream>
using namespace std;
const int POINTNUM = 5;
typedef struct XET {
    int x;
    int dx, ymax;
    struct XET* next;
}AET, NET;
struct Point {
    int x;
    int y;
    Point() {}
    Point(int x, int y) {
        this->x = x;
        this->y = y;
    }
}polypoint[POINTNUM];
int MaxY, MinY;//多边形顶点沿Y轴的最小值和最大值
void Init(){
    polypoint[0] = Point(100,100);
    polypoint[1] = Point(100,300);
    polypoint[2] = Point(200,200);
    polypoint[3] = Point(300,300);
    polypoint[4] = Point(300,100);
    MaxY = polypoint[0].y;
    MinY = polypoint[0].y;
    for (int i = 0; i < POINTNUM; i++) {
        if (polypoint[i].y > MaxY) {
            MaxY = polypoint[i].y;
        }
        if (polypoint[i].y < MinY) {
            MinY = polypoint[i].y;
        }
    }
}
void PolyScan() {
    glBegin(GL_POINTS);
    glColor3f(0.0, 1.0, 0.0);//设置颜色的函数
    // 请在此添加你的代码
   /********** Begin ********/
     AET* pAET = new AET;
    pAET->next = NULL;
    NET* pNET[1024];
    for (int i = MinY; i <= MaxY; i++) {
        pNET[i] = new NET;
        pNET[i]->next = NULL;
    }
    //填NET表
    for (int i = MinY; i <= MaxY; i++)
    {
        for (int j = 0; j < POINTNUM; j++)
        {
            if (polypoint[j].y == i)
            {
                if (polypoint[(j - 1 + POINTNUM) % POINTNUM].y > polypoint[j].y) //左边的点
                {
                    NET* p = new NET;
                    p->x = polypoint[j].x;
                    p->ymax = polypoint[(j - 1 + POINTNUM) % POINTNUM].y;
                    p->dx = (polypoint[(j - 1 + POINTNUM) % POINTNUM].x - polypoint[j].x) / (polypoint[(j - 1 + POINTNUM) % POINTNUM].y - polypoint[j].y);
                    p->next = pNET[i]->next;
                    pNET[i]->next = p;
                }
                if (polypoint[(j + 1 + POINTNUM) % POINTNUM].y > polypoint[j].y)  //右边的点
                {
                    NET* p = new NET;
                    p->x = polypoint[j].x;
                    p->ymax = polypoint[(j + 1 + POINTNUM) % POINTNUM].y;
                    p->dx = (polypoint[(j + 1 + POINTNUM) % POINTNUM].x - polypoint[j].x) / (polypoint[(j + 1 + POINTNUM) % POINTNUM].y - polypoint[j].y);
                    p->next = pNET[i]->next;
                    pNET[i]->next = p;
                }
            }
        }
    }
    //建立更新AET
    for (int i = MinY; i <= MaxY; i++) {
        //计算新的交点x,更新AET
        NET* p = pAET->next;
        while (p != NULL)
        {
            p->x = p->x + p->dx;
            p = p->next;
        }
        //更新后新AET先排序
        //断表排序,不再开辟空间
        AET* tq = pAET;
        p = pAET->next;
        tq->next = NULL;
        while (p != NULL)  //按x排序
        {
            while (tq->next != NULL && p->x >= tq->next->x)
            {
                tq = tq->next;
            }
            NET* s = p->next;
            p->next = tq->next;
            tq->next = p;
            p = s;
            tq = pAET;
        }
        AET* q = pAET;
        p = q->next;
        while (p != NULL)
        {
            if (p->ymax == i)
            {
                q->next = p->next;
                delete p;
                p = q->next;
            }
            else
            {
                q = q->next;
                p = q->next;
            }
        }
        //将NET中的新点加入AET,并用插入法按X值递增排序
        p = pNET[i]->next;
        q = pAET;
        while (p != NULL)
        {
            while (q->next != NULL && p->x >= q->next->x)
            {
                q = q->next;
            }
            NET* s = p->next;
            p->next = q->next;
            q->next = p;
            p = s;
            q = pAET;
        }
        p = pAET->next;
        while (p && p->next)
        {
            for (float j = p->x; j <= p->next->x; j++)
                glVertex2f(j, i);
            p = p->next->next;//考虑端点情况
        }
    }
    NET* phead = NULL;
    NET* pnext = NULL;
    //释放活跃边表
    phead = pAET;
    while (phead != NULL)
    {
        pnext = phead->next;
        delete phead;
        phead = pnext;
    }
   /********** End **********/
    glEnd();
}
void LineGL(int i){
    glBegin(GL_LINES);
    glColor3f(0.0f, 1.0f, 0.0f);
    glVertex2f(polypoint[i].x, polypoint[i].y);
    glVertex2f(polypoint[i + 1].x, polypoint[i + 1].y);
    if (i == POINTNUM - 2) {
        glVertex2f(polypoint[0].x, polypoint[0].y);
        glVertex2f(polypoint[i + 1].x, polypoint[i + 1].y);
    }
    glEnd();
}
void MyDisplay()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0f, 1.0f, 1.0f);
    for (int i = 0; i < POINTNUM - 1; i++) {
        LineGL(i);
    }
   PolyScan();
   glFlush();
}
void MyReshape(int w, int h)
{
    glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);
}
int main(int argc, char* argv[])
{
    glutInit(&argc, argv);//窗口的初始化
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//窗口谋模式的设定
    glutInitWindowPosition(100, 100);//窗口位置的设定
    glutInitWindowSize(400, 400);//窗口大小的设定
    glutCreateWindow("多边形的扫描填充");
    Init();
    glutDisplayFunc(MyDisplay);
    glutReshapeFunc(MyReshape);
    glutMainLoopEvent();
    /*************以下为评测代码,与本次实验内容无关,请勿修改**************/
  GLubyte* pPixelData = (GLubyte*)malloc(400 * 400 * 3);//分配内存
    GLint viewport[4] = {0};    
    glReadBuffer(GL_FRONT);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    glGetIntegerv(GL_VIEWPORT, viewport);
    glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);
  cv::Mat img;
    std::vector<cv::Mat> imgPlanes;
    img.create(400, 400, CV_8UC3);
    cv::split(img, imgPlanes);
    for(int i = 0; i < 400; i ++) {
        unsigned char* plane0Ptr = imgPlanes[0].ptr<unsigned char>(i);
        unsigned char* plane1Ptr = imgPlanes[1].ptr<unsigned char>(i);
        unsigned char* plane2Ptr = imgPlanes[2].ptr<unsigned char>(i);
        for(int j = 0; j < 400; j ++) {
            int k = 3 * (i * 400 + j);
            plane2Ptr[j] = pPixelData[k];
            plane1Ptr[j] = pPixelData[k+1];
            plane0Ptr[j] = pPixelData[k+2];
        }
    }
    cv::merge(imgPlanes, img);
    cv::flip(img, img ,0); 
    cv::namedWindow("openglGrab");
    cv::imshow("openglGrab", img);
    cv::imwrite("../img_step1/test.jpg", img);
  return 0;
}

第2关:边缘填充法

// 评测代码所用头文件-开始
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
// 评测代码所用头文件-结束
// 提示:写完代码请保存之后再进行评测
#include<GL/freeglut.h>
#include<math.h>
#include<string>
#include <iostream>
using namespace std;
const int POINTNUM = 5;
struct Point {
    int x;
    int y;
    Point() {}
    Point(int x, int y) {
        this->x = x;
        this->y = y;
    }
}polypoint[POINTNUM];
int MaxY, MinY;//多边形顶点沿Y轴的最小值和最大值
int vis[400][400];//判断该坐标的点是否为填充色,0为背景色,1为填充色
void Init() {
    polypoint[0] = Point(100, 100);
    polypoint[1] = Point(100, 300);
    polypoint[2] = Point(200, 200);
    polypoint[3] = Point(300, 300);
    polypoint[4] = Point(300, 100);
}
void EdgeFilling() {
    // 请在此添加你的代码
   /********** Begin ********/
     int i, j, x, y, t;
    float k;
    for (i = 0; i < POINTNUM; i++) {
        if (i == 0)
            t = POINTNUM - 1;
        else
            t = i - 1;
        if (polypoint[t].y <= polypoint[i].y) {
            MinY = polypoint[t].y;
            MaxY = polypoint[i].y;
            j = polypoint[t].x;
            if (polypoint[t].x == polypoint[i].x) {
                k = 0;
            }
            else
                k = (float)(polypoint[i].y - polypoint[t].y) / (float)(polypoint[i].x - polypoint[t].x);
        }
        else {
            MinY = polypoint[i].y;
            MaxY = polypoint[t].y;
            j = polypoint[i].x;
            if (polypoint[t].x == polypoint[i].x) {
                k = 0;
            }
            else
                k = (float)(polypoint[t].y - polypoint[i].y) / (float)(polypoint[t].x - polypoint[i].x);
        }
        for (y = MinY; y < MaxY; y++) {
            for (x = j; x < 400; x++) {
                if (vis[x][y] == 1)
                    vis[x][y] = 0;
                else
                    vis[x][y] = 1;
            }
            j += k ;
        }
    }
   /********** End **********/
    glBegin(GL_POINTS);
    glColor3f(0.0, 1.0, 0.0);//设置颜色的函数
    for (int x = 0; x < 400; x++) {
        for (int y = 0; y < 400; y++) {
            if (vis[x][y] == 1) {
                glVertex2f(x, y);
            }
        }
    }
    glEnd();
}
void LineGL(int i){
    glBegin(GL_LINES);
    glColor3f(0.0f, 1.0f, 0.0f);
    glVertex2f(polypoint[i].x, polypoint[i].y);
    glVertex2f(polypoint[i + 1].x, polypoint[i + 1].y);
    if (i == POINTNUM - 2) {
        glVertex2f(polypoint[0].x, polypoint[0].y);
        glVertex2f(polypoint[i + 1].x, polypoint[i + 1].y);
    }
    glEnd();
}
void MyDisplay()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0f, 1.0f, 1.0f);
    for (int i = 0; i < POINTNUM - 1; i++) {
        LineGL(i);
    }
   EdgeFilling();
    glFlush();
}
void MyReshape(int w, int h)
{
    glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);
}
int main(int argc, char* argv[])
{
    glutInit(&argc, argv);//窗口的初始化
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//窗口谋模式的设定
    glutInitWindowPosition(100, 100);//窗口位置的设定
    glutInitWindowSize(400, 400);//窗口大小的设定
    glutCreateWindow("多边形的扫描填充");
    Init();
    glutDisplayFunc(MyDisplay);//调用函数
    glutReshapeFunc(MyReshape);
    glutMainLoopEvent();
    /*************以下为评测代码,与本次实验内容无关,请勿修改**************/
  GLubyte* pPixelData = (GLubyte*)malloc(400 * 400 * 3);//分配内存
    GLint viewport[4] = {0};    
    glReadBuffer(GL_FRONT);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    glGetIntegerv(GL_VIEWPORT, viewport);
    glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);
  cv::Mat img;
    std::vector<cv::Mat> imgPlanes;
    img.create(400, 400, CV_8UC3);
    cv::split(img, imgPlanes);
    for(int i = 0; i < 400; i ++) {
        unsigned char* plane0Ptr = imgPlanes[0].ptr<unsigned char>(i);
        unsigned char* plane1Ptr = imgPlanes[1].ptr<unsigned char>(i);
        unsigned char* plane2Ptr = imgPlanes[2].ptr<unsigned char>(i);
        for(int j = 0; j < 400; j ++) {
            int k = 3 * (i * 400 + j);
            plane2Ptr[j] = pPixelData[k];
            plane1Ptr[j] = pPixelData[k+1];
            plane0Ptr[j] = pPixelData[k+2];
        }
    }
    cv::merge(imgPlanes, img);
    cv::flip(img, img ,0); 
    cv::namedWindow("openglGrab");
    cv::imshow("openglGrab", img);
    cv::imwrite("../img_step2/test.jpg", img);
  return 0;
}

第3关:区域四连通种子填充算法

// 评测代码所用头文件-开始
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
// 评测代码所用头文件-结束
// 提示:写完代码请保存之后再进行评测
#include<GL/freeglut.h>
#include<math.h>
#include<string>
#include <iostream>
using namespace std;
const int POINTNUM = 5;
struct Point {
    int x;
    int y;
    Point() {}
    Point(int x, int y) {
        this->x = x;
        this->y = y;
    }
}polypoint[POINTNUM];
int MaxY, MinY;//多边形顶点沿Y轴的最小值和最大值
int vis[400][400];//判断该坐标的点是否为填充色,0为背景色,1为填充色
void Init() {
    polypoint[0] = Point(100, 100);
    polypoint[1] = Point(100, 300);
    polypoint[2] = Point(200, 200);
    polypoint[3] = Point(300, 300);
    polypoint[4] = Point(300, 100);
}
void BoundaryFill4(int x, int y) {  
    // 请在此添加你的代码
   /********** Begin ********/
    if (vis[x][y] == 0) {
        vis[x][y] = 1;
        glVertex2f(x, y);
        BoundaryFill4(x + 1, y);
        BoundaryFill4(x - 1, y);
        BoundaryFill4(x, y + 1);
        BoundaryFill4(x, y - 1);
    }
   /********** End **********/
}
void BoundaryPoly() {
    int i, t, k, x, y;
    for (i = 0; i < POINTNUM; i++) {
        i == 0 ? t = POINTNUM - 1 : t = i - 1;
        if (polypoint[i].y >= polypoint[t].y) {
            MinY = polypoint[t].y;
            MaxY = polypoint[i].y;
            x = polypoint[t].x;
            if (polypoint[t].x == polypoint[i].x) {
                k = 0;
            }
            else
                k = (float)(polypoint[i].y - polypoint[t].y) / (float)(polypoint[i].x - polypoint[t].x);
        }
        else
        {
            MinY = polypoint[i].y;
            MaxY = polypoint[t].y;
            x = polypoint[i].x;
            if (polypoint[t].x == polypoint[i].x) {
                k = 0;
            }
            else
                k = (float)(polypoint[t].y - polypoint[i].y) / (float)(polypoint[t].x - polypoint[i].x);
        }
        for (y = MinY; y < MaxY; y++) {
            glVertex2f(x, y);
            vis[x][y] = 1;
            x += k;
        }
        if (polypoint[t].y == polypoint[i].y && polypoint[i].x > polypoint[t].x) {
            for (x = polypoint[t].x; x < polypoint[i].x; x++) {
                glVertex2f(x, polypoint[t].y);
                vis[x][y] = 1;
            }
        }
        else if (polypoint[t].y == polypoint[i].y && polypoint[i].x < polypoint[t].x) {
            for (x = polypoint[i].x; x < polypoint[t].x; x++) {
                glVertex2f(x, polypoint[t].y);
                vis[x][y] = 1;
            }
        }
    }
}
void MyDisplay()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0f, 1.0f, 1.0f);
    glBegin(GL_POINTS);
    glColor3f(0.0, 1.0, 0.0);//设置颜色的函数
    //将边界用像素表示并输出;
    BoundaryPoly();
    BoundaryFill4(200, 150);
    glEnd();
    glFlush();
}
void MyReshape(int w, int h)
{
    glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);
}
int main(int argc, char* argv[])
{
    glutInit(&argc, argv);//窗口的初始化
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//窗口谋模式的设定
    glutInitWindowPosition(100, 100);//窗口位置的设定
    glutInitWindowSize(400, 400);//窗口大小的设定
    glutCreateWindow("多边形的扫描填充");
    Init();
    glutDisplayFunc(MyDisplay);//调用函数
    glutReshapeFunc(MyReshape);
    glutMainLoopEvent();
    /*************以下为评测代码,与本次实验内容无关,请勿修改**************/
  GLubyte* pPixelData = (GLubyte*)malloc(400 * 400 * 3);//分配内存
    GLint viewport[4] = {0};    
    glReadBuffer(GL_FRONT);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    glGetIntegerv(GL_VIEWPORT, viewport);
    glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);
  cv::Mat img;
    std::vector<cv::Mat> imgPlanes;
    img.create(400, 400, CV_8UC3);
    cv::split(img, imgPlanes);
    for(int i = 0; i < 400; i ++) {
        unsigned char* plane0Ptr = imgPlanes[0].ptr<unsigned char>(i);
        unsigned char* plane1Ptr = imgPlanes[1].ptr<unsigned char>(i);
        unsigned char* plane2Ptr = imgPlanes[2].ptr<unsigned char>(i);
        for(int j = 0; j < 400; j ++) {
            int k = 3 * (i * 400 + j);
            plane2Ptr[j] = pPixelData[k];
            plane1Ptr[j] = pPixelData[k+1];
            plane0Ptr[j] = pPixelData[k+2];
        }
    }
    cv::merge(imgPlanes, img);
    cv::flip(img, img ,0); 
    cv::namedWindow("openglGrab");
    cv::imshow("openglGrab", img);
    cv::imwrite("../img_step3/test.jpg", img);
  return 0;
}

第4关:区域扫描线种子填充算法

// 评测代码所用头文件-结束// 提示:写完代码请保存之后再进行评测
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
// 评测代码所用头文件-开始
#include<GL/freeglut.h>
#include<math.h>
#include<string>
#include <iostream>
#include<stack>
using namespace std;
const int POINTNUM = 5;
struct Point {
    int x;
    int y;
    Point() {}
    Point(int x, int y) {
        this->x = x;
        this->y = y;
    }
}polypoint[POINTNUM];
int MaxY, MinY;//多边形顶点沿Y轴的最小值和最大值
int vis[400][400];//判断该坐标的点是否为填充色,0为背景色,1为填充色
void Init() {
    polypoint[0] = Point(100, 100);
    polypoint[1] = Point(100, 300);
    polypoint[2] = Point(200, 200);
    polypoint[3] = Point(300, 300);
    polypoint[4] = Point(300, 100);
}
void FindNewSeed(stack<Point>& s,int left,int right,int y) {
    for (int i = left + 1; i < right; i++) {
        if (vis[i][y] == 0) {
            int j = i + 1;
            while (vis[j][y] == 0)
                j++;
            i = j--;
            s.push(Point(j, y));
        }
    }
}
void ScanLineFlood(int x, int y) { 
    stack<Point> s;
    Point p;
    int left, right;
    s.push(Point(x, y));
    while (!s.empty()) {
        //栈顶元素出栈
        p = s.top();
        s.pop();
        //向左填充
        for (left = p.x; vis[left][p.y] != 1; left--) {
            glVertex2f(left, p.y);
            vis[left][p.y] = 1;
        }    
        //向右填充
        for (right = p.x + 1; vis[right][p.y] != 1; right++) { 
            glVertex2f(right, p.y);
            vis[right][p.y] = 1;
        }
        //在当前行的下一行寻找确定新的种子点
        FindNewSeed(s, left, right, p.y - 1); 
        //在当前行的上一行寻找确定新的种子点
        FindNewSeed(s, left, right, p.y + 1); 
    }
}
void BoundaryPoly() {
    int i, t, k, x, y;
    for (i = 0; i < POINTNUM; i++) {
        i == 0 ? t = POINTNUM - 1 : t = i - 1;
        if (polypoint[i].y >= polypoint[t].y) {
            MinY = polypoint[t].y;
            MaxY = polypoint[i].y;
            x = polypoint[t].x;
            if (polypoint[t].x == polypoint[i].x) {
                k = 0;
            }
            else
                k = (float)(polypoint[i].y - polypoint[t].y) / (float)(polypoint[i].x - polypoint[t].x);
        }
        else
        {
            MinY = polypoint[i].y;
            MaxY = polypoint[t].y;
            x = polypoint[i].x;
            if (polypoint[t].x == polypoint[i].x) {
                k = 0;
            }
            else
                k = (float)(polypoint[t].y - polypoint[i].y) / (float)(polypoint[t].x - polypoint[i].x);
        }
        for (y = MinY; y < MaxY; y++) {
            glVertex2f(x, y);
            vis[x][y] = 1;
            x += k;
        }
        if (polypoint[t].y == polypoint[i].y && polypoint[i].x > polypoint[t].x) {
            for (x = polypoint[t].x; x < polypoint[i].x; x++) {
                glVertex2f(x, polypoint[t].y);
                vis[x][y] = 1;
            }
        }
        else if (polypoint[t].y == polypoint[i].y && polypoint[i].x < polypoint[t].x) {
            for (x = polypoint[i].x; x < polypoint[t].x; x++) {
                glVertex2f(x, polypoint[t].y);
                vis[x][y] = 1;
            }
        }
    }
}
void MyDisplay()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0f, 1.0f, 1.0f);
    glBegin(GL_POINTS);
    glColor3f(0.0, 1.0, 0.0);//设置颜色的函数
    //将边界用像素表示并输出;
    BoundaryPoly();
    ScanLineFlood(200, 150);
    glEnd();
    glFlush();
}
void MyReshape(int w, int h)
{
    glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);
}
int main(int argc, char* argv[])
{
    glutInit(&argc, argv);//窗口的初始化
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//窗口谋模式的设定
    glutInitWindowPosition(100, 100);//窗口位置的设定
    glutInitWindowSize(400, 400);//窗口大小的设定
    glutCreateWindow("多边形的扫描填充");
    Init();
    glutDisplayFunc(MyDisplay);//调用函数
    glutReshapeFunc(MyReshape);
    glutMainLoopEvent();
    /*************以下为评测代码,与本次实验内容无关,请勿修改**************/
    GLubyte* pPixelData = (GLubyte*)malloc(400 * 400 * 3);//分配内存
    GLint viewport[4] = {0};
    glReadBuffer(GL_FRONT);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    glGetIntegerv(GL_VIEWPORT, viewport);
    glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);
   cv::Mat img;
    std::vector<cv::Mat> imgPlanes;
    img.create(400, 400, CV_8UC3);
    cv::split(img, imgPlanes);
        for(int i = 0; i < 400; i ++) {
            unsigned char* plane0Ptr = imgPlanes[0].ptr<unsigned char>(i);
            unsigned char* plane1Ptr = imgPlanes[1].ptr<unsigned char>(i);
            unsigned char* plane2Ptr = imgPlanes[2].ptr<unsigned char>(i);
            for(int j = 0; j < 400; j ++) {
                int k = 3 * (i * 400 + j);
                plane2Ptr[j] = pPixelData[k];
                plane1Ptr[j] = pPixelData[k+1];
                plane0Ptr[j] = pPixelData[k+2];
            }
        }
        cv::merge(imgPlanes, img);
        cv::flip(img, img ,0); 
        cv::namedWindow("openglGrab");
        cv::imshow("openglGrab", img);
        //cv::waitKey();
        cv::imwrite("../img_step4/test.jpg", img);
  return 0;
}


相关文章
|
6月前
|
存储 算法 索引
模拟算法题练习(二)(DNA序列修正、无尽的石头)
模拟算法题练习(二)(DNA序列修正、无尽的石头)
|
6月前
|
并行计算 算法 测试技术
模拟算法题练习(一)(扫雷,灌溉,回文日期)
模拟算法题练习(一)(扫雷,灌溉,回文日期)
|
1月前
|
算法 测试技术 C++
【动态规划算法】蓝桥杯填充问题(C/C++)
【动态规划算法】蓝桥杯填充问题(C/C++)
|
5月前
|
机器学习/深度学习 算法 测试技术
如何应对缺失值带来的分布变化?探索填充缺失值的最佳插补算法
该文探讨了缺失值插补的不同方法,比较了它们恢复数据真实分布的效果。文章指出,处理插补尤其在小样本或复杂数据时是个挑战,需要选择能适应数据分布变化的方法。文中介绍了完全随机缺失(MCAR)、随机缺失(MAR)和非随机缺失(MNAR)三种机制,并以一个简单的例子展示了数据分布变化。文章通过比较均值插补、回归插补和高斯插补,强调了高斯插补在重现数据分布方面更优。评估插补方法时,不应仅依赖于RMSE,而应关注分布预测,使用如能量距离这样的指标。此外,即使在随机缺失情况下,数据分布也可能因模式变化而变化,需要考虑适应这些变化的插补方法。
150 2
|
5月前
|
存储 算法 数据挖掘
python5种算法模拟螺旋、分层填充、递归、迭代、分治实现螺旋矩阵ll【力扣题59】
python5种算法模拟螺旋、分层填充、递归、迭代、分治实现螺旋矩阵ll【力扣题59】
|
5月前
|
算法 Java 计算机视觉
图像处理之泛洪填充算法(Flood Fill Algorithm)
图像处理之泛洪填充算法(Flood Fill Algorithm)
262 6
|
6月前
|
算法
多边形裁剪算法
多边形裁剪算法
多边形扫描转换-扫描线算法
多边形扫描转换-扫描线算法
|
6月前
|
算法 图形学
【计算机图形学】实验一 DDA算法、Bresenham算法
【计算机图形学】实验一 DDA算法、Bresenham算法
208 3
|
6月前
|
算法 图形学
【计算机图形学】实验三 用Cohen-Sutherland裁剪算法实现直线段裁剪
【计算机图形学】实验三 用Cohen-Sutherland裁剪算法实现直线段裁剪
441 2