原文作者:aircraft

原文地址:https://www.cnblogs.com/DOMLX/p/9598974.html

        我看了一下发现关于c++下的CImage图像处理类 的图像处理相关的介绍真的是比较少,因为我要做大二的数据结构的课程设计,要用纯c++语言去实现(老师不让调用opencv之类图像处理库),所以自己就尝试写了很多操作处理的代码,下面都是我课设用到的代码段,我已经降低耦合度分离出来了,并且全部都是用指针对内存的操作,这样速度比较快,现在就全部分享出来吧。

前人栽树,后人乘凉

望与诸君共勉。

        MFC图像处理CImage类常用操作

CImage类头文件为#include<atlimage.h>

CImage类读取图片CImage.Load("src.bmp");

CImage类保存图片CImage.Save("dst.jpg");

一.CImage类实例拷贝数据到另外一个CImage类实例

bool ImageCopy(const CImage &srcImage, CImage &destImage)
{
int i, j;//循环变量
if (srcImage.IsNull())
return FALSE;
//源图像参数
BYTE* srcPtr = (BYTE*)srcImage.GetBits();
int srcBitsCount = srcImage.GetBPP();
int srcWidth = srcImage.GetWidth();
int srcHeight = srcImage.GetHeight();
int srcPitch = srcImage.GetPitch();
//销毁原有图像
if (!destImage.IsNull())
{
destImage.Destroy();
}
//创建CImage类新图像并分配内存
if (srcBitsCount == ) //支持alpha通道
{
destImage.Create(srcWidth, srcHeight, srcBitsCount, );
}
else
{
destImage.Create(srcWidth, srcHeight, srcBitsCount, );
}
//加载调色板
if (srcBitsCount <= && srcImage.IsIndexed())//需要调色板
{
RGBQUAD pal[];
int nColors = srcImage.GetMaxColorTableEntries();
if (nColors>)
{
srcImage.GetColorTable(, nColors, pal);
destImage.SetColorTable(, nColors, pal);//复制调色板程序
}
}
//目标图像参数
BYTE *destPtr = (BYTE*)destImage.GetBits();
int destPitch = destImage.GetPitch();
//复制图像数据
for (i = ; i<srcHeight; i++)
{
memcpy(destPtr + i*destPitch, srcPtr + i*srcPitch, abs(srcPitch));
} return TRUE;
}

二.CImage类实例处理图像间的腐蚀运算

//腐蚀运算
//width:图像宽;height:图像高;矩形掩膜的边长(2*r+1)void erosion(CImage image, int width, int height, int r)
{
int i, j, m, n;
int flag;
//unsigned char * pBuff = tempBuff;
CImage Buff;
ImageCopy(image, Buff);
//dataCopy(image, pBuff, width, height);
byte *pImg = (byte *)image.GetBits();
byte *pBuff = (byte *)Buff.GetBits();
int step = image.GetPitch();
//int height = image.GetHeight();
//int width = image.GetWidth();
for (i = r; i<height - r; i++)
{
for (j = r; j<width - r; j++)
{
flag = ;
for (m = i - r; m <= i + r; m++)
{
for (n = j - r; n <= j + r; n++)
{
//if (!pBuff[i*width + j] || !pBuff[m*width + n])
if (!*(pBuff + i*step + j) || !*(pBuff + m*step + n))
{
flag = ;
break;
}
}
}
if (flag == )
{
*(pImg + i*step + j) = ;
}
else
{
*(pImg + i*step + j) = ;
}
}
}
}

三.CImage类实例处理图像间的膨胀运算

//膨胀运算
//width:图像宽;height:图像高;矩形掩膜的边长(2*r+1)
void diate(CImage image, int width, int height, int r)
{
int i, j, m, n;
int flag;
//unsigned char * pBuff = tempBuff; CImage Buff;
ImageCopy(image, Buff);
//dataCopy(image, pBuff, width, height);
byte *pImg = (byte *)image.GetBits();
byte *pBuff = (byte *)Buff.GetBits();
int step = image.GetPitch();
//int height = image.GetHeight();
//int width = image.GetWidth();
//dataCopy(image, pBuff, width, height);
for (i = r; i<height - r; i++)
{
for (j = r; j<width - r; j++)
{
flag = ;
for (m = i - r; m <= i + r; m++)
{
for (n = j - r; n <= j + r; n++)
{
if ( == *(pBuff + i*step + j) || == *(pBuff + m*step + n))
{
flag = ;
break;
}
}
}
if (flag == )
{
*(pImg + i*step + j) = ;
}
else
{
*(pImg + i*step + j) = ;
}
}
}
}

四.CImage类实例处理图片遍历赋值操作

    byte *pImg = (byte *)imgSrc.GetBits();
int step = imgSrc.GetPitch();
int height = imgSrc.GetHeight();
int width = imgSrc.GetWidth();
int sum = ;
unsigned char val = ;
//初始化
for (int i = ; i<maxY; i++)
for (int j = ; j<maxX; j++)
*(pDstImg + i*step + j) = ;

五.用CImage类实例遍历生成手指静脉边缘图

#define  mlen  9 //模板长度
//加长扩展的水平边缘检测模板
int upperEdgeOperator[mlen * ] =
{
-, -, -, -, -, -, -, -, -,
, , , , , , , , ,
, , , , , , , ,
};
int lowerEdgeOperator[mlen * ] =
{
, , , , , , , , ,
, , , , , , , , ,
-, -, -, -, -, -, -, -, -
}; int findEdgesHorizontal(CImage& imgSrc, CImage& imgDst)
{
int maxY = imgSrc.GetHeight();
int maxX = imgSrc.GetWidth(); if (!imgDst.IsNull())
{
imgDst.Destroy();
}
imgDst.Create(maxX, maxY, , );//图像大小与imgSrc相同,每个像素占1字节 if (imgDst.IsNull())
return FALSE; byte *pImg = (byte *)imgSrc.GetBits();
byte *pDstImg = (byte *)imgDst.GetBits();
int step = imgSrc.GetPitch();
int height = imgSrc.GetHeight();
int width = imgSrc.GetWidth();
int sum = ;
unsigned char val = ;
//初始化
for (int i = ; i<maxY; i++)
for (int j = ; j<maxX; j++)
*(pDstImg + i*step + j) = ; //找上边缘
for (int i = ; i <maxY / - ; i++)
{
for (int j = ; j < maxX - ; j++)
{
sum = ;
for (int m = -; m <= ; m++)
{
for (int n = -mlen / ; n <= mlen / ; n++)
{
sum += *(pImg + (i + m)*step + (j + n))*upperEdgeOperator[(m + )*mlen + (n + mlen / )];
}
}
sum = sum < ? : sum;
sum = sum > ? : sum;
val = unsigned char(sum);
*(pDstImg + i*step + j) = val;
}
}
//找下边缘
for (int i = maxY / + ; i <maxY - ; i++)
{
for (int j = ; j < maxX - ; j++)
{
sum = ;
for (int m = -; m <= ; m++)
{
for (int n = -mlen / ; n <= mlen / ; n++)
{
sum += *(pImg + (i + m)*step + (j + n))*upperEdgeOperator[(m + )*mlen + (n + mlen / )];;
}
}
sum = sum < ? : sum;
sum = sum > ? : sum;
val = unsigned char(sum);
*(pDstImg + i*step + j) = val;
}
} return TRUE;
}

六.CImage图像类实例将RGB图转为灰度(gary)图

BOOL ImageToGray(CImage& imgSrc, CImage& imgDst)
{
int maxY = imgSrc.GetHeight();
int maxX = imgSrc.GetWidth(); if (!imgDst.IsNull())
{
imgDst.Destroy();
}
imgDst.Create(maxX, maxY, , );//图像大小与imgSrc相同,每个像素占1字节 if (imgDst.IsNull())
return FALSE; //为imgDst构造256阶灰度调色表
RGBQUAD ColorTab[];
for (int i = ; i<; i++)
{
ColorTab[i].rgbBlue = ColorTab[i].rgbGreen = ColorTab[i].rgbRed = i;
}
imgDst.SetColorTable(, , ColorTab); byte* pDataSrc = (byte*)imgSrc.GetBits(); //获取指向图像数据的指针
byte* pDataDst = (byte*)imgDst.GetBits();
int pitchSrc = imgSrc.GetPitch(); //获取每行图像占用的字节数 +:top-down;-:bottom-up DIB
int pitchDst = imgDst.GetPitch();
int bitCountSrc = imgSrc.GetBPP() / ; // 获取每个像素占用的字节数
int bitCountDst = imgDst.GetBPP() / ;
if ((bitCountSrc != ) || (bitCountDst != ))
return FALSE;
int tmpR, tmpG, tmpB, avg;
for (int i = ; i<maxX; i++)
{
for (int j = ; j<maxY; j++)
{
tmpR = *(pDataSrc + pitchSrc*j + i*bitCountSrc);
tmpG = *(pDataSrc + pitchSrc*j + i*bitCountSrc + );
tmpB = *(pDataSrc + pitchSrc*j + i*bitCountSrc + );
avg = (int)(tmpR + tmpG + tmpB) / ;
*(pDataDst + pitchDst*j + i*bitCountDst) = avg;
}
}
return TRUE;
}

七.CImage类转opencv Mat类  以及Mat类转CImage类

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include "CimgMat.h" void CimgMat::MatToCImage(Mat& mat, CImage& cimage)
{
if ( == mat.total())
{
return;
} int nChannels = mat.channels();
if (( != nChannels) && ( != nChannels))
{
return;
}
int nWidth = mat.cols;
int nHeight = mat.rows; //重建cimage
cimage.Destroy();
cimage.Create(nWidth, nHeight, * nChannels); //拷贝数据 uchar* pucRow; //指向数据区的行指针
uchar* pucImage = (uchar*)cimage.GetBits(); //指向数据区的指针
int nStep = cimage.GetPitch(); //每行的字节数,注意这个返回值有正有负 if ( == nChannels) //对于单通道的图像需要初始化调色板
{
RGBQUAD* rgbquadColorTable;
int nMaxColors = ;
rgbquadColorTable = new RGBQUAD[nMaxColors];
cimage.GetColorTable(, nMaxColors, rgbquadColorTable);
for (int nColor = ; nColor < nMaxColors; nColor++)
{
rgbquadColorTable[nColor].rgbBlue = (uchar)nColor;
rgbquadColorTable[nColor].rgbGreen = (uchar)nColor;
rgbquadColorTable[nColor].rgbRed = (uchar)nColor;
}
cimage.SetColorTable(, nMaxColors, rgbquadColorTable);
delete[]rgbquadColorTable;
} for (int nRow = ; nRow < nHeight; nRow++)
{
pucRow = (mat.ptr<uchar>(nRow));
for (int nCol = ; nCol < nWidth; nCol++)
{
if ( == nChannels)
{
*(pucImage + nRow * nStep + nCol) = pucRow[nCol];
}
else if ( == nChannels)
{
for (int nCha = ; nCha < ; nCha++)
{
*(pucImage + nRow * nStep + nCol * + nCha) = pucRow[nCol * + nCha];
}
}
}
}
} void CimgMat::CImageToMat(CImage& cimage, Mat& mat)
{
if (true == cimage.IsNull())
{
return;
} int nChannels = cimage.GetBPP() / ;
if (( != nChannels) && ( != nChannels))
{
return;
}
int nWidth = cimage.GetWidth();
int nHeight = cimage.GetHeight(); //重建mat
if ( == nChannels)
{
mat.create(nHeight, nWidth, CV_8UC1);
}
else if ( == nChannels)
{
mat.create(nHeight, nWidth, CV_8UC3);
} //拷贝数据 uchar* pucRow; //指向数据区的行指针
uchar* pucImage = (uchar*)cimage.GetBits(); //指向数据区的指针
int nStep = cimage.GetPitch(); //每行的字节数,注意这个返回值有正有负 for (int nRow = ; nRow < nHeight; nRow++)
{
pucRow = (mat.ptr<uchar>(nRow));
for (int nCol = ; nCol < nWidth; nCol++)
{
if ( == nChannels)
{
pucRow[nCol] = *(pucImage + nRow * nStep + nCol);
}
else if ( == nChannels)
{
for (int nCha = ; nCha < ; nCha++)
{
pucRow[nCol * + nCha] = *(pucImage + nRow * nStep + nCol * + nCha);
}
}
}
}
}

八.纯图像数据赋值给CImage后的初始化,并且写入调色板

bool InitalImage(CImage &image, int width, int height)
{
if (image.IsNull())
image.Create(width, height, );
else
{
if (width <= || height <= )
return false;
else if (image.GetHeight() == width && image.GetWidth() == height)
return true;
else
{
image.Destroy();
image.Create(width, height, );
}
}
//写入调色板
RGBQUAD ColorTable[];
image.GetColorTable(, , ColorTable);
for (int i = ; i < ; i++)
{
ColorTable[i].rgbBlue = (BYTE)i;
ColorTable[i].rgbGreen = (BYTE)i;
ColorTable[i].rgbRed = (BYTE)i;
}
image.SetColorTable(, , ColorTable);
return true;
}

九.根据MFC控件大小CImage类实例图片显示

if(m_image2.IsNull())    //判断有无图像
return; // 取得客户区尺寸
CRect zcRect;
GetDlgItem(IDC_STATIC_PIC2)->GetClientRect(&zcRect); // 将图像显示在界面之上
m_image2.Draw(GetDlgItem(IDC_STATIC_PIC2)->GetDC()->m_hDC,
zcRect.left,
zcRect.top,
zcRect.Width(),
zcRect.Height());

十.根据CImage类实例图片调整控件大小显示图片

    if(m_image1.IsNull())
return; // 将整控件调整为与图像同一尺寸
GetDlgItem(IDC_STATIC_PIC)->SetWindowPos(NULL,
0,0,m_image1.GetWidth(), m_image1.GetHeight(),
SWP_NOMOVE); CRect zcRect;
GetDlgItem(IDC_STATIC_PIC)->GetClientRect(&zcRect); m_image1.Draw(GetDlgItem(IDC_STATIC_PIC)->GetDC()->m_hDC,
zcRect.left,
zcRect.top,
zcRect.Width(),
zcRect.Height());

十一.CImage类与CBitmap转换

    CImage nImage;
nImage.Load(imgFilePath); HBITMAP hBitmap=nImage.Detach(); // 获得位图句柄 用以转换 // 转换方式一:
CBitmap bmp;
bmp.DeleteObject();
bmp.Attach(hBitmap); // 转换为CBitmap对象 // 转换方式二: CBitmap *pBitmap=CBitmap::FromHandle(nImage.m_hBitmap);

十二.CImage类实例实现图像二值化

void imgBinary(CImage image, int imgW, int imgH, int threshold)
{
int i;
int index = ;
byte *pImg = (byte *)image.GetBits();
int step = image.GetPitch();
int height = image.GetHeight();
int width = image.GetWidth();
for (i = ; i<height*width; i++)
{
*(pImg + index) = *(pImg + index)>threshold ? : ;
index++;
} }

十三.CImage实现自己的argmax函数----求图像一定高度区域中某一列遇到的第一个最大像素值的坐标并返回

int  argmax(CImage &image,int Top,int Bottom,int x)
{
int max = ;
int tem;
int pos = ;
byte *pImg = (byte *)image.GetBits();
int step = image.GetPitch();
int height = image.GetHeight();
int width = image.GetWidth();
if (Top > && Top < height && Bottom > && Bottom < height && x > && x < width)
{
for (int i = Top; i < Bottom; ++i)
{
tem = *(pImg + i*step + x);
if (tem > max)
{
max = tem;
pos = i;
} }
return pos;
}
else
{
return FALSE;
} }

十四.CImage类创建指定长宽图像并初始化调色板

bool InitalImage(CImage &image, int width, int height)
{
if (image.IsNull())
image.Create(width, height, );
else
{
if (width <= || height <= )
return false;
else if (image.GetHeight() == width && image.GetWidth() == height)
return true;
else
{
image.Destroy();
image.Create(width, height, );
}
}
//写入调色板
RGBQUAD ColorTable[];
image.GetColorTable(, , ColorTable);
for (int i = ; i < ; i++)
{
ColorTable[i].rgbBlue = (BYTE)i;
ColorTable[i].rgbGreen = (BYTE)i;
ColorTable[i].rgbRed = (BYTE)i;
}
image.SetColorTable(, , ColorTable);
return true;
}

十五.将存放在一维指针数组里的图像数据赋值给CImage类实例

void LoadImageData(CImage &image, unsigned char * data)
{
if (data == nullptr)
return;
byte *pS;
byte *pImg = (byte *)image.GetBits();
int step = image.GetPitch();
int height = image.GetHeight();
int width = image.GetWidth();
for (int i = ; i < image.GetHeight(); ++i)
{
pS = data + i * width;
for (int j = ; j < image.GetWidth(); ++j)
{
*(pImg + i*step + j) = pS[j];
}
}
}

十六.CImage类自己实现图片的裁剪

//裁剪roi区域
void RoiCut(CImage &image, CImage &roiImg, int heightTop,int heightDown,int widthBegin,int widthEnd)
{
InitalImage(roiImg, heightDown - heightTop + , widthBegin - widthEnd + );
byte *pImg = (byte *)image.GetBits();
byte *pRoi = (byte *)roiImg.GetBits();
int step = image.GetPitch();
int height = image.GetHeight();
int width = image.GetWidth();
int index = ;
for (int i = heightTop; i < heightDown; i++)
{
for (int j = widthBegin; j < widthEnd; j++)
{
*(pRoi + index) = *(pImg + i*step + j);
index++;
}
} }

十七.CImage类截取电脑屏幕图片,也就是屏幕截图的意思

#include"iostream"
#include<atlimage.h> int main()
{
HDC hDCScreen = ::GetDC(NULL);//首先获取到屏幕的句柄
int nBitPerPixel = GetDeviceCaps(hDCScreen, BITSPIXEL);//获取到每个像素的bit数目
int nWidthScreen = GetDeviceCaps(hDCScreen, HORZRES);
int nHeightScreen = GetDeviceCaps(hDCScreen, VERTRES);
//创建一个CImage的对象
CImage m_MyImage;
//Create实例化CImage,使得其内部的画布大小与屏幕一致
m_MyImage.Create(nWidthScreen, nHeightScreen, nBitPerPixel);
//获取到CImage的 HDC,但是需要手动ReleaseDC操作,下面是MSDN的说明
//Because only one bitmap can be selected into a device context at a time,
//you must call ReleaseDC for each call to GetDC.
HDC hDCImg = m_MyImage.GetDC(); //使用bitblt 将屏幕的DC画布上的内容 拷贝到CImage上
BitBlt(hDCImg, , , nWidthScreen, nHeightScreen, hDCScreen, , , SRCCOPY); //直接保存吧
m_MyImage.Save("C:\\test.bmp", Gdiplus::ImageFormatBMP);
m_MyImage.Save("C:\\test.png", Gdiplus::ImageFormatPNG);
m_MyImage.Save("C:\\test.jpeg", Gdiplus::ImageFormatJPEG); //前面调用了GetDC所以需要调用ReleaseDC释放掉
//详情请参见MSDN
m_MyImage.ReleaseDC();
return ;
}

十八.CImage转为CBitmap以及CBitmap转CImage

#include<atlimage.h>
#include<afxwin.h> void cimageToCbitmap(CImage & srcImg, CBitmap & dstImg)
{ HBITMAP hbmp = (HBITMAP)srcImg.operator HBITMAP(); dstImg.DeleteObject(); dstImg.Attach(hbmp);
} void cbitmapToCimage(CBitmap & srcImg, CImage & dstImg)
{
HBITMAP hbmp = (HBITMAP)srcImg.GetSafeHandle(); if (!dstImg.IsNull()) //Attach前,必须确认img中无位图,否则会弹出异常,但忽略也可继续运行
dstImg.Destroy(); dstImg.Attach(hbmp); //另注:原对象中的位图改变后,所有Attach到这个对象的对象需从新Attach一次,否则图像为初始化的颜色或黑色!
}

十八.CImage类实现图形旋转90度(通过计算旋转矩阵之后的位置直接映射过去)

CImage * srcImg = new CImage();

    srcImg->Load(strPicName);
BYTE* srcPtr = (BYTE*)srcImg->GetBits();
int srcBitsCount = srcImg->GetBPP();
int srcWidth = srcImg->GetWidth();
int srcHeight = srcImg->GetHeight();
int srcPitch = srcImg->GetPitch(); //删除原始图片 DeleteFile(strPicName); //创建新图像 CImage * dstImg = new CImage();
dstImg->Create(, , srcBitsCount, ); //加载调色板
if (srcBitsCount <= && srcImg->IsIndexed())//需要调色板
{
RGBQUAD pal[];
int nColors = srcImg->GetMaxColorTableEntries();
if (nColors > )
{
srcImg->GetColorTable(, nColors, pal);
dstImg->SetColorTable(, nColors, pal);//复制调色板程序
}
}
//目标图像参数
BYTE *destPtr = (BYTE*)dstImg->GetBits();
int destPitch = dstImg->GetPitch();
int width = dstImg->GetWidth();
int height = dstImg->GetHeight();
//复制图像数据
for (int i = ; i < height; i++)
{
for (int j = ; j < width; j++) { if(srcBitsCount == ) { *(destPtr + ( - j)*destPitch + * i) = *(srcPtr + i * srcPitch + * j);//目的图片的第一列
*(destPtr + ( - j)*destPitch + * i + ) = *(srcPtr + i * srcPitch + * j + ); *(destPtr + ( - j)*destPitch + * i + ) = *(srcPtr + i * srcPitch + * j + ); } else if(srcBitsCount == ) { *(destPtr + ( - j)*destPitch + i) = *(srcPtr + i * srcPitch + j);//目的图片的第一列 } }
} //保存新图像
dstImg->Save(strPicName);
delete srcImg;
delete dstImg;

还有一些操作比较麻烦这里就先不写了,后面想到什么在写把嘿嘿。

参考博客:https://blog.csdn.net/ishallwin/article/details/4840180

参考博客:https://blog.csdn.net/shuilan0066/article/details/7080244

若有兴趣交流分享技术,可关注本人公众号,里面会不定期的分享各种编程教程,和共享源码,诸如研究分享关于c/c++,python,前端,后端,opencv,halcon,opengl,机器学习深度学习之类有关于基础编程,图像处理和机器视觉开发的知识

c++ MFC图像处理CImage类常用操作代码的更多相关文章

  1. legend3---lavarel常用操作代码

    legend3---lavarel常用操作代码 一.总结 一句话总结: 要自己总结一下常用代码,这样才方便,也才有收获 1.路由示例:Route::get('/login','Home\Login\L ...

  2. 使用matlab进行图像处理的一些常用操作和tip

    本人还是习惯使用Python语言,有时候不得不使用matlab的时候就变得举步维艰,下面记录一下使用matlab进行图像处理的一些常用操作以及代码,方便之后查阅: 1. 图像的读取 %% 读取原图像 ...

  3. legend3---lavarel常用操作代码2

    legend3---lavarel常用操作代码2 一.总结 一句话总结: 对于王思cong被执法人的感悟:失意时 莫心伤,得意时 莫膨胀 1.lavarel自动事务? DB::transaction方 ...

  4. legend3---Homestead常用操作代码

    legend3---Homestead常用操作代码 一.总结 一句话总结: 在虚拟机里面改变文件windows里面也会变,在windows里面改变虚拟机里面也会变,所以可以在windows里面编程或者 ...

  5. 二叉树的python可视化和常用操作代码

    二叉树是一个重要的数据结构, 本文基于"二叉查找树"的python可视化 pybst 包, 做了一些改造, 可以支持更一般的"二叉树"可视化. 关于二叉树和二叉 ...

  6. [Swift]字符串(String类、NSString类)常用操作

    NS是Cocoa类对象类型的前缀,来源于乔布斯建立的另一家公司--NeXTNSString的使用方法,和Swift语言中的String有很多相似之处. 1.字符串的定义String类 var str1 ...

  7. 【java】String类和StringBuffer类常用操作

    String类是字符串常量,是不可更改的常量.而StringBuffer是字符串变量,它的对象是可以扩充和修改的.StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于Stri ...

  8. js常用操作代码

    页面前进后退<input type=button value=刷新 onclick="window.location.reload()"><input type= ...

  9. C++字符串string类常用操作详解(一)【初始化、遍历、连接】

    代码示例: #include <iostream> #include "string" using namespace std; //字符串初始化 void strIn ...

随机推荐

  1. iOS应用审核时间注意点

    1.重大节假日不审核 美国重大节假日期间不审核,具体审核时间查看官方通知

  2. 【ARC075F】Mirrored 搜索/数位dp

    Description ​ 给定正整数DD,求有多少个正整数NN,满足rev(N)=N+Drev(N)=N+D,其中rev(N)rev(N)表示将NN的十进制表示翻转来读得到的数 Input ​ 一个 ...

  3. cf555e

    cf555e(缩点) 给一个 n 个点 m 条边的图,以及 q 对点 (s,t),让你给 m 条边定向.问是否存在一种方案,使每对点的 s 能走到 t. \(n,m,q≤ 2×10^5\). 首先,在 ...

  4. loj #6046. 「雅礼集训 2017 Day8」爷

    #6046. 「雅礼集训 2017 Day8」爷 题目描述 如果你对山口丁和 G&P 没有兴趣,可以无视题目背景,因为你估计看不懂 …… 在第 63 回战车道全国高中生大赛中,军神西住美穗带领 ...

  5. 洛谷P4011 孤岛营救问题(状压+BFS)

    传送门 和网络流有半毛钱关系么…… 可以发现$n,m,p$都特别小,那么考虑状压,每一个状态表示位置以及钥匙的拥有情况,然后每次因为只能走一步,所以可以用bfs求出最优解 然后是某大佬说的注意点:每个 ...

  6. Python DataFrame 如何删除原来的索引,重新建立索引

    删除行索引重排: ser.reset_index(drop = True) df.reset_index(drop = True) ---------------------------------- ...

  7. opencv学习笔记(五)----图像的形态学操作

    图像的形态学操作有基本的腐蚀和膨胀操作和其余扩展形态学变换操作(高级操作)-----开运算,闭运算,礼帽(顶帽)操作,黑帽操作...(主要也是为了去噪声,改善图像) 形态学操作都是用于处理二值图像(其 ...

  8. 在makefile通过宏定义来控制源程序的编译

    在Makefile中我们可以通过宏定义来控制源程序的编译.只要在Makefile中的CFLAGS中通过选项-D来指定你于定义的宏即可. 如:CFLAGS += -D _XXX在编译的时候加上此选项就可 ...

  9. gnome-terminal

    在终端中打开终端: gnome-terminal 同时打开多个终端: gnome-terminal --window --window 此处有几个 --window 就会打开几个终端 最大化形式打开终 ...

  10. 网址访问量统计插件 FlagCounter

    网址或博客访问量统计插件  ---> FlagCounter. 网址:http://s01.flagcounter.com/more/ERP2/