zoukankan      html  css  js  c++  java
  • 图像处理加强版

    /*
    像素是指由图像的小方格组成的,是图像的最小单位,以一个单一颜色的小格存在。
    */
    #include <graphics.h>
    #include <conio.h>   
    #include <stdio.h>
    
    
    //将图片转换为马赛克效果
    //算法:求出每个小方块内所有像素的颜色平均值,然后用来设置为该小方块的颜色。
    //依次处理每个小方块,即可实现马赛克效果。
    //pimg:图片地址  tilesize:方块尺寸  startx,starty:起始坐标
    void Mosaic(IMAGE *pimg, int tilesize, int startx, int starty)
    {
        int width = pimg->getwidth();      // 获取图像的宽   640
        int height = pimg->getheight(); // 获取图像的高      480
        int redsum;         // 红色值的和
        int greensum;       // 绿色值的和
        int bluesum;        // 蓝色值的和
        int count;          // 每个小方块内的像素数量
        int color;          // 每个像素的颜色
        int x, y, tx, ty;   // 循环变量
    
        // 获取指向显存的指针
        DWORD* pMem = GetImageBuffer(pimg);
    
        // 求出左上角第一个方块的坐标
        startx = (startx % tilesize == 0 ? 0 : startx % tilesize - tilesize);//0
        starty = (starty % tilesize == 0 ? 0 : starty % tilesize - tilesize);//0
    
        // 处理每一个小方块
        for (y = starty; y < height; y += tilesize)//0-10-20...480
        for (x = startx; x < width; x += tilesize)//0-10-20...640
        {
            // 清空累加值
            redsum = greensum = bluesum = count = 0;
    
            // 求小方块的红、绿、蓝颜色值的和
            //遍历小方块每一个像素点
            for (ty = min(y + tilesize, height) - 1; ty >= max(y, 0); ty--)//9-8-7...0
            for (tx = min(x + tilesize, width) - 1; tx >= max(x, 0); tx--)//9-8-7...0
            {
                color = pMem[ty * width + tx];//9*640+9 给每一个像素点赋值
                redsum += GetRValue(color);//求出三原色的值
                greensum += GetGValue(color);
                bluesum += GetBValue(color);
                count++;//像素点的数量
            }
    
            // 求红、绿、蓝颜色的平均值
            redsum /= count;
            greensum /= count;
            bluesum /= count;
    
            // 设置小方块内的每个像素为平均颜色值
            color = RGB(redsum, greensum, bluesum);
            //遍历每一个小方块
            for (ty = min(y + tilesize, height) - 1; ty >= max(y, 0); ty--)
            for (tx = min(x + tilesize, width) - 1; tx >= max(x, 0); tx--)
                pMem[ty * width + tx] = color;//讲求出的整个方块像素的平均值赋给方块
        }
    }
    
    // 将图片进行模糊处理
    //算法:遍历图片像素,将每个像素颜色值与其周围像素颜色值求和,取平均值对其赋值
    void Blur(IMAGE *pimg)
    {
        DWORD*  pMem = GetImageBuffer(pimg);// 获取指向显存的指针
    
        COLORREF color;
        int r, g, b;
        int num = 0;//像素点位置
        int width = pimg->getwidth();//获取图像的宽度
        int height = pimg->getheight();//获取图像的高度
        int m, n, i;//循环变量
    
        // 计算 9 格方向系数 -641      -640     -639        -1  0  1     639     640      641
        int cell[9] = { -(width + 1), -width, -(width - 1), -1, 0, 1, width - 1, width, width + 1 };
    
        // 逐个像素点读取计算 640*480-1 0 
        for (i = width * height - 1; i >= 0; i--)
        {
            // 累加周围 9 格颜色值
            for (n = 0, m = 0; n < 9; n++)
            {
                // 位置定位
                num = i + cell[n];//640*480-1-641  640*480-1-640 640
    
                // 判断位置值是否越界
                if (num < 0 || num >= width * height)
                {
                    color = RGB(0, 0, 0);       // 将越界像素赋值为0
                    m++;                        // 统计越界像素数
                }
                else
                    color = pMem[num];//讲当前像素点的颜色值赋给color
    
                // 累加颜色值
                r += GetRValue(color);
                g += GetGValue(color);
                b += GetBValue(color);
            }
            // 将平均值赋值该像素
            pMem[i] = RGB(r / (9 - m), g / (9 - m), b / (9 - m));
            r = g = b = 0;
        }
    }
    
    // 底片效果
    /*
    底片效果使用如下公式:
    
    pMem[i] = (~pMem[i]) & 0x00FFFFFF
    */
    void ColorInvert(IMAGE *pimg)
    {
        // 获取指向显存的指针
        DWORD* pMem = GetImageBuffer(pimg);
    
        // 直接对显存赋值,遍历每一个像素点
        for (int i = pimg->getwidth() * pimg->getheight() - 1; i >= 0; i--)
            pMem[i] = (~pMem[i]) & 0x00FFFFFF;//111111111111 000011111111
        /*
        分析操作数0x00ffffff的二进制值为32位,最高8位为0,其余为1,综合按位与的运算规则,
        可以知道结果的最高8位为0,剩余24位与左边操作数的低24位值相同。
        于是a&0x00ffffff就是取a的低24位,即低3字节的值。
        比如0x12345678 & 0x00ffffff = 0x00345678。
        */
    }
    
    // 彩色图像转换为灰度图像
    /*
    灰度图是指只含亮度信息,不含色彩信息的图象
    彩色转换为灰度使用如下公式:
    
    Gray = R * 0.299 + G * 0.587 + B * 0.114
    为了提高运算速度,将这个公式转换为整数运算:
    
    Gray = (R * 229 + G * 587 + B * 114 + 500) / 1000
    
    
    */
    void  ColorToGray(IMAGE *pimg)
    {
        DWORD *p = GetImageBuffer(pimg);
        COLORREF c;
    
        // 逐个像素点读取计算
        for (int i = pimg->getwidth() * pimg->getheight() - 1; i >= 0; i--)
        {
            c = BGR(p[i]);//用于交换颜色中的蓝色和红色
            c = (GetRValue(c) * 299 + GetGValue(c) * 587 + GetBValue(c) * 114 + 500) / 1000;
            p[i] = RGB(c, c, c);    // 由于是灰度值,无需再执行 BGR 转换
        }
    }
    
    // 主函数
    void main()
    {
        // 初始化绘图环境
        initgraph(640, 480);
    
        // 获取图像
        IMAGE img;
        loadimage(&img, _T("1.jpg"));
    
        // 显示原始图像
        putimage(0, 0, &img);
    
        // 任意键执行11111
        //_getch();
        setbkmode(0);
        settextcolor(BLACK);
        outtextxy(200, 150, "请选择要对图片进行的处理:");
        outtextxy(250, 200, "a.马赛克效果");
        outtextxy(250, 250, "b.模糊效果");
        outtextxy(250, 300, "c.底片效果");
        outtextxy(250, 350, "d.灰度效果");
    
        switch (_getch())
        {
        case 'a':
            // 将图片转换为马赛克效果
            Mosaic(&img, 10, 0, 0);
            // 显示处理后的图像
            putimage(0, 0, &img);
            break;
        case 'b':
            // 模糊处理 10 次
            for (int m = 0; m < 10; m++)
                Blur(&img);
            // 显示处理后的图像
            putimage(0, 0, &img);
            break;
        case 'c':
            // 底片效果
            ColorInvert(&img);
            // 显示处理后的图像
            putimage(0, 0, &img);
            break;
        case 'd':
            // 处理图像为灰度
            ColorToGray(&img);
            // 显示处理后的图像
            putimage(0, 0, &img);
            break;
        default:
            loadimage(&img, _T("1.jpg"));
    
            // 显示原始图像
            putimage(0, 0, &img);
            break;
    
        }
    
        // 任意键关闭绘图环境
        _getch();
        closegraph();
    }
  • 相关阅读:
    c#自动更新+安装程序的制作
    VS2013项目受源代码管理向源代码管理注册此项目时出错
    WinDbg配置和使用基础
    InstallShield Limited Edition for Visual Studio 2013 图文教程(教你如何打包.NET程序)
    PowerDesigner 如何生成数据库更新脚本
    用户故事(User Story)
    Troubleshooting Record and Playback issues in Coded UI Test
    Coded UI
    compare two oracle database schemas
    How to: Use Schema Compare to Compare Different Database Definitions
  • 原文地址:https://www.cnblogs.com/506941763lcj/p/9880261.html
Copyright © 2011-2022 走看看